在前文中我们已经学习了:线程的基本情况如何创建多线程线程的生命周期。利用已有知识我们已经可以写出如何利用多线程处理大量任务这样简单的程序。但是当应用场景复杂时,我们还需要从管理控制入手,更好的操纵多线程。在第一节中我们讲过,使用多线程的好处之一就是我们可以通过编码和已有类库更好的管理和控制多线程。接下来我会详细的介绍如何管理多线程,包括:对线程的等待、守护线程、线程的睡眠、线程的突然停止、线程的让步、线程的优先级等。由于内容比较多,本节先介绍前两部分:对线程的等待、守护线程


1、线程的等待

我们常常对同一件事情进行切割,分成多干件小的事情后,再开辟多条线程来处理(有点分治的味道)。在多件事情处理完成之后我们需要再统一的处理。这样说有点枯燥:比如我们要导出一份文件,这个文件的行数非常多大概几十万行数据。直接导出也可以,会导致系统卡一下,严重一点的可能会超时。这时候怎么办呢?我们可以分成若干份,比如每五千条数据是一份数据,然后用一条线程去导出到文件中,这样就会生成若干份文件。当所有的文件都导出后,我们把这些数据汇总一下就OK了。但是这里有一个问题,什么时候所有线程都导完数据了呢?我们总不能一个一个的去检查文件是否存在吧。

这里java为我们提供了一个专门用于等待的方法Join().当某条线程执行了其他线程的join()方法以后,当前线程就会阻塞,直到其他线程执行结束以后,才可以运行。

如下述代码:

 public class newThread extends Thread
{
public newThread(String name)
{
super(name);
}
public void run()
{
int i=100;
while(i-->0)
{
sleep(100);
}
} public static void main(String args)throws Exception
{
Thread son_1=new newThread("thread-1");
Thread son_2=new newThread("thread-2");
son_1.start();
son_2.start();
son_1.join();//注意这里
son_2.join();
System.out.println("all threads is over")
}
}

我们分别启动thread 1 和thread 2。这两条线程会分别运行,互相不影响,然后我们用主线程来等待线程1,直到它结束,我们才开始等待线程2。如果线程1比线程2的用时长的话,再我们等待完线程1 后,线程2将无需等待,直接输出结果。
join方法共有三种形式的重载

 join()
join(long millis)//
join(long millis,int nanos)//millis 毫秒 nanos微秒

第一个方法时直到等待线程结束才继续向下运行,第二和第三个方法则是在限定时间内等待,如果时间结束将不会继续等待(可以用于超时判断),注意第三个方法并不常用,这里主要是因为java和硬件对时间的把控根本难以精确到微秒级,所以并不能很准确到控制。


2、守护线程

    守护线程(Daemon Thread)又叫做精灵线程、后台线程。乍一听守护二字,觉得好像很厉害的意思,像是在保护其他线程的线程,其实很简单,并没有那么玄。所有的语言设计,都是为了更方便的使用。(防盗连接:本文首发自王若伊_恩赐解脱http://www.cnblogs.com/jilodream/ )

  设想这样一个场景:在一个考场内,考生们都在埋头答卷,除了考生,还有监考老师,他的职责就是为了维护考场的秩序,对于有困难的考生提供帮助。当所有的考生都交卷后(或者时间到了以后,考生被强制交卷(结束线程)),这个监考老师的义务已经完成,无需继续运行。简而言之,这个监考老师是为了其他学生提供后台服务的,当所有的考生都已经停笔后,老师的义务也已经结束了,可以退场了。

  有些人看到这里,可能会觉得,这还不简单,我们只要如线程等待让老师等待所有的学生都结束之后,不就可以了么?!这个回答对也不对。对的是老师的线程的确是在等待学生线程结束,不对的地方是老师线程在等待的同时,还在提供服务,并不是所有学生停笔后收卷这么简单。在Jvm中有一个所有开发者都熟悉的线程GC,它就是在其他线程运行的同时,默默的提供服务,当其他线程结束后,他又默默的退场。

如下代码

 public class newThread extends Thread
{
public newThread(String name)
{
super(name);
}
public void run()
{
int i=100;
while(i-->0)
{
sleep(100);
}
} public static void main(String args)throws Exception
{
Thread son_1=new newThread("thread-1");
Thread son_2=new newThread("thread-2");
Thread daemonThread=new newThread("thread-daemonThread");
son_1.start();
son_2.start(); daemonThread.setDaemon(true);//注意看这里
daemonThread.start();
son_1.join();
son_2.join();
System.out.println("all son_threads is over")
}
} class DaemonThread
{
public DaemonThread(String name)
{
super(name);
}
public void run()
{
int i=1000;
while(i-->0)
{
sleep(100);
}
}
}

  在代码中 Daemonthread线程被设置为后台线程,则当主线程等待子线程结束后, Daemonthread线程也会结束,不会继续运行。我们可以用这种方式设置一种线程,专门用来维护其他线程的正常运行,比如后台计数,计时,查询各个客户端是否保持在线(心跳),推送事件等。
java还专门提供了 IsDaemon()的方法来判断这个线程是否为后台线程。

这里有一点注意的是,如果要设置一个线程为后台线程,必须要在这个线程还没有开始“就绪”(start())时设置,否则会引发非法的线程状态异常

Java多线程开发系列之四:玩转多线程(线程的控制1)的更多相关文章

  1. Java多线程开发系列之一:走进多线程

    对编程语言的基础知识:分支.选择.循环.面向对象等基本概念理解后,我们需要对java高级编程有一定的学习,这里不可避免的要接触到多线程开发. 由于多线程开发整体的系统比较大,我会写一个系列的文章总结介 ...

  2. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  3. Java多线程开发系列之番外篇:事件派发线程---EventDispatchThread

    事件派发线程是java Swing开发中重要的知识点,在安卓app开发中,也是非常重要的一点.今天我们在多线程开发中,穿插进来这个线程.分别从线程的来由.原理和使用方法三个方面来学习事件派发线程. 一 ...

  4. Java SE开发系列-JDK下载安装

    JDK下载安装 JDK是Java的开发环境,目前JDK内部也包含了JRE,JRE主要是JAVA程序的运行环境. 点击官方下载地址,按着下图操作即可下载对应系统的不同版本JDK. 进入页面滑到页面底部点 ...

  5. java高并发系列 - 第9天:用户线程和守护线程

    守护线程是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回收线程.JIT线程都是守护线程.与之对应的是用户线程,用户线程可以理解为是系统的工作线程,它会完成这个程序需要完成的业务操作.如果 ...

  6. Java多线程开发系列之二:如何创建多线程

    前文已介绍过多线程的基本知识了,比如什么是多线程,什么又是进程,为什么要使用多线程等等. 在了解了软件开发中使用多线程的基本常识后,我们今天来聊聊如何简单的使用多线程. 在Java中创建多线程的方式有 ...

  7. Java多线程开发系列之三:线程这一辈子(线程的生命周期)

    前文中已经提到了,关于多线程的基础知识和多线程的创建.但是如果想要很好的管理多线程,一定要对线程的生命周期有一个整体概念.本节即对线程的一生进行介绍,让大家对线程的各个时段的状态有一定了解. 线程的一 ...

  8. Java多线程开发系列之五:Springboot 中异步请求方法的使用

    Springboot 中异步线程的使用在过往的后台开发中,我们往往使用java自带的线程或线程池,来进行异步的调用.这对于效果来说没什么,甚至可以让开发人员对底层的状况更清晰,但是对于代码的易读性和可 ...

  9. Windows多线程同步系列之四-----信号量

    信号量说实话自己没怎么使用过.书上大概这样说,信号量设置一个资源访问计数.当该计数值大于0的时候,该信号量对象 为有信号状态,当该计数值等于0的时候,该信号量对象为无信号状态. 我们来查几个主要的AP ...

随机推荐

  1. css疑难汇总

    关于a标签不换行顶开容器的问题(转自): 我们用div,p,ul,li(等块级元素)布局给其设定了特定的width,那么就会自动的换行.用span,a(等内联元素)设置了display:inline- ...

  2. 初学Less

    使用Less Server-side usage npm安装 命令行使用 在代码中使用 Client-side usage 语言特性 Variables Mixins Nested Rules Ope ...

  3. scrapy爬虫笔记(一)------环境配置

    前言: 本系列文章是对爬虫的简单介绍,以及教你如何用简单的方法爬取网站上的内容. 需要阅读者对html语言及python语言有基本的了解. (本系列文章也是我在学习爬虫过程中的学习笔记,随着学习的深入 ...

  4. Python之路第一课Day1--随堂笔记

    课堂大纲: 一.Python介绍 二.发展史 三.Python 2 or 3? 四.安装 五.Hello World程序 六.变量 七.用户输入 八.模块初识 九..pyc是个什么鬼? 十.数据类型初 ...

  5. USACO翻译:USACO 2014 MARCH GOLD P2 Sabotage

    1.破坏{DOLD题2} sabotage.pas/c/cpp [问题描述] 农夫约翰的头号敌人保罗决定破坏农民约翰的挤奶设备.挤奶设备排成一行,共N(3<= N <=100000)台挤奶 ...

  6. opencv的问题

    opencv中图像文件格式是BRG的顺序 而QImage是RGB形式 H:色彩 S:深浅 s=0 只有灰度 V:明暗

  7. windows计划任务+批处理文件实现oracle数据库的定时备份与恢复

    1.  备份: PS:2014-1-15 如果导出的dmp数据文件不大的话,就直接每天导出好了,不要只保存七天的数据.然后顶起通过winrar对文件进行打包,我发现dmp文件的压缩包还是很高的. 那么 ...

  8. 动态加载多国语言 ---- cookie + 浏览器

    一.多国语言缩写列表 因为涉及到浏览器的可接收语言,所以需要知道各个国家的语言缩写. 这个百度一下即可. en 英文 en_US 英文 (美国) ar 阿拉伯文 ar_AE 阿拉伯文 (阿拉伯联合酋长 ...

  9. pptv泥够了!pptv“关闭”事件为营销炒作坐实!

    昨天还让人心生怜悯的pptv聚力,今天下午2点07分又再一次发布微博,而几天发布的内容是see U again!再次证实了pptv昨天的“关闭”还是“倒闭”消息为营销炒作.不过马浩周要问了,真的要这么 ...

  10. Enum

    1.定义时使用enum关键字定义. 2.隐式继承了java.lang.Enum类,所以不能再继承其他类了. 3.隐式的final修饰符,所以不能被其他类继承. package enumTest; pu ...