`
wb284551926
  • 浏览: 538632 次
文章分类
社区版块
存档分类
最新评论

Java线程(四):线程中断、线程让步、线程睡眠、线程合并(转载)

 
阅读更多

       本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/17560467,转载请注明。
       最近在Review线程专栏,修改了诸多之前描述不够严谨的地方,凡是带有Review标记的文章都是修改过了。本篇文章是插进来的,因为原来没有写,现 在来看传统线程描述的不太完整,所以就补上了。理解了线程同步和线程通信之后,再来看本文的知识点就会简单的多了,本文是做为传统线程知识点的一个补充。 有人会问:JDK5之后有了更完善的处理多线程问题的类(并发包),我们还需要去了解传统线程吗?答:需要。在实际开发中,无外乎两种情况,一个是开发新 内容,另一个是维护原有程序。开发新内容可以使用新的技术手段,但是我们不能保证原有程序是用什么实现的,所以我们需要了解原有的。另外一点,了解传统线 程的工作原理,使我们在使用并发包时更加得心应手。

 

 

线程中断

 

 

 

       线程中断涉及到三个方法,如下:

 

void interrupt()
          中断线程。
static boolean interrupted()
          测试当前线程是否已经中断。
boolean isInterrupted()
          测试线程是否已经中断。

       interrupt()方法用于中断线程,通常的理解来看,只要某个线程启动后,调用了该方法,则该线程不能继续执行了,来看个小例子:

  1. public class InterruptTest {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         MyThread t = new MyThread("MyThread");  
  4.         t.start();  
  5.         Thread.sleep(100);// 睡眠100毫秒  
  6.         t.interrupt();// 中断t线程  
  7.     }  
  8. }  
  9. class MyThread extends Thread {  
  10.     int i = 0;  
  11.     public MyThread(String name) {  
  12.         super(name);  
  13.     }  
  14.     public void run() {  
  15.         while(true) {// 死循环,等待被中断  
  16.             System.out.println(getName() + getId() + "执行了" + ++i + "次");  
  17.         }  
  18.     }  
  19. }  

       运行后,我们发现,线程t一直在执行,没有被中断,原来interrupt()是骗人的,汗!其实interrupt()方法并不是中断线程的执行,而 是为调用该方法的线程对象打上一个标记,设置其中断状态为true,通过isInterrupted()方法可以得到这个线程状态,我们将上面的程序做一 个小改动:

  1. public class InterruptTest {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         MyThread t = new MyThread("MyThread");  
  4.         t.start();  
  5.         Thread.sleep(100);// 睡眠100毫秒  
  6.         t.interrupt();// 中断t线程  
  7.     }  
  8. }  
  9. class MyThread extends Thread {  
  10.     int i = 0;  
  11.     public MyThread(String name) {  
  12.         super(name);  
  13.     }  
  14.     public void run() {  
  15.         while(!isInterrupted()) {// 当前线程没有被中断,则执行  
  16.             System.out.println(getName() + getId() + "执行了" + ++i + "次");  
  17.         }  
  18.     }  
  19. }  

 

       这样的话,线程被顺利的中断执行了。很多人实现一个线程类时,都会再加一个flag标记,以便控制线程停止执行,其实完全没必要,通过线程自身的中断状 态,就可以完美实现该功能。如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 我们可以捕获该异常,并且做一些处理。另外,Thread.interrupted()方法是一个静态方法,它是判断当前线程的中断状态,需要注意的是, 线程的中断状态会由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。

 

 

 

线程让步

 

 

 

       线程让步,其方法如下:
static void yield()
          暂停当前正在执行的线程对象,并执行其他线程

       线程让步用于正在执行的线程,在某些情况下让出CPU资源,让给其它线程执行,来看一个小例子:

  1. public class YieldTest {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         // 创建线程对象  
  4.         YieldThread t1 = new YieldThread("t1");  
  5.         YieldThread t2 = new YieldThread("t2");  
  6.         // 启动线程  
  7.         t1.start();  
  8.         t2.start();  
  9.         // 主线程休眠100毫秒  
  10.         Thread.sleep(100);  
  11.         // 终止线程  
  12.         t1.interrupt();  
  13.         t2.interrupt();  
  14.     }  
  15. }  
  16. class YieldThread extends Thread {  
  17.     int i = 0;  
  18.     public YieldThread(String name) {  
  19.         super(name);  
  20.     }  
  21.     public void run() {  
  22.         while(!isInterrupted()) {  
  23.             System.out.println(getName() + "执行了" + ++i + "次");  
  24.             if(i % 10 == 0) {// 当i能对10整除时,则让步  
  25.                 Thread.yield();  
  26.             }  
  27.         }  
  28.     }  
  29. }  

 

       输出结果略,从输出结果可以看到,当某个线程(t1或者t2)执行到10次、20次、30次等时,就会马上切换到另一个线程执行,接下来再交替执行,如此往复。注意,如果存在synchronized线程同步的话,线程让步不会释放锁(监视器对象)

 

 

 

线程睡眠

 

 

 

       线程睡眠涉及到两个方法,如下:
static void sleep(long millis)
          在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。
static void sleep(long millis, int nanos)
          在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)。

       线程睡眠的过程中,如果是在synchronized线程同步内,是持有锁(监视器对象)的,也就是说,线程是关门睡觉的,别的线程进不来,来看一个小例子:

  1. public class SleepTest {  
  2.     public static void main(String[] args) {  
  3.         // 创建共享对象  
  4.         Service service = new Service();  
  5.         // 创建线程  
  6.         SleepThread t1 = new SleepThread("t1", service);  
  7.         SleepThread t2 = new SleepThread("t2", service);  
  8.         // 启动线程  
  9.         t1.start();  
  10.         t2.start();  
  11.     }  
  12.       
  13. }  
  14. class SleepThread extends Thread {  
  15.     private Service service;  
  16.     public SleepThread(String name, Service service) {  
  17.         super(name);  
  18.         this.service = service;  
  19.     }  
  20.     public void run() {  
  21.         service.calc();  
  22.     }  
  23. }  
  24. class Service {  
  25.     public synchronized void calc() {  
  26.         System.out.println(Thread.currentThread().getName() + "准备计算");  
  27.         System.out.println(Thread.currentThread().getName() + "感觉累了,开始睡觉");  
  28.         try {  
  29.             Thread.sleep(10000);// 睡10秒  
  30.         } catch (InterruptedException e) {  
  31.             return;  
  32.         }  
  33.         System.out.println(Thread.currentThread().getName() + "睡醒了,开始计算");  
  34.         System.out.println(Thread.currentThread().getName() + "计算完成");  
  35.     }  
  36. }  

       输出结果:

  1. t1准备计算  
  2. t1感觉累了,开始睡觉  
  3. t1睡醒了,开始计算  
  4. t1计算完成  
  5. t2准备计算  
  6. t2感觉累了,开始睡觉  
  7. t2睡醒了,开始计算  
  8. t2计算完成  

 

 

 

线程合并

 

 

 

       线程合并涉及到三个方法,如下:
 void join()
          等待该线程终止。
 void join(long millis)
          等待该线程终止的时间最长为 millis 毫秒。
 void join(long millis, int nanos)
          等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。

 

       线程合并是优先执行调用该方法的线程,再执行当前线程,来看一个小例子:
  1. public class JoinTest {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         JoinThread t1 = new JoinThread("t1");  
  4.         JoinThread t2 = new JoinThread("t2");  
  5.         t1.start();  
  6.         t2.start();  
  7.         t1.join();  
  8.         t2.join();  
  9.         System.out.println("主线程开始执行!");  
  10.     }  
  11. }  
  12. class JoinThread extends Thread {  
  13.     public JoinThread(String name) {  
  14.         super(name);  
  15.     }  
  16.     public void run() {  
  17.         for(int i = 1; i <= 10; i++)  
  18.             System.out.println(getName() + getId() + "执行了" + i + "次");  
  19.     }  
  20. }  
       t1和t2都执行完才继续主线程的执行,所谓合并,就是等待其它线程执行完,再执行当前线程,执行起来的效果就好像把其它线程合并到当前线程执行一样。

 

 

 

线程优先级

 

 

 

       线程最低优先级为1,最高优先级为10,看起来就有10个级别,但这10个级别能不能和CPU对应上,还未可知,Thread类中提供了优先级的三个常量,如下: java.lang.Thread
public static final int MAX_PRIORITY 10
public static final int MIN_PRIORITY 1
public static final int NORM_PRIORITY 5
       我们创建线程对象后,如果不显示的设置优先级的话,默认为5。优先级可以看成一种特权,优先级高的,获取CPU调度的机会就大,优先级低的,获取CPU调度的机会就小,这个和我们现实生活很一样啊,优胜劣汰。线程优先级的示例就不写了,比较简单。

 

 

 

wait()和sleep()区别

 

 

 

       区别太大了,但是在Java线程面试题中是很常见的问题,相信你阅读过本专栏后,能够轻松的解答,这里不再赘述。

       本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/17560467,转载请注明。

分享到:
评论

相关推荐

    java多线程编程总结

    Java线程:线程的调度-让步 Java线程:线程的调度-合并 Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 ...

    Java多线程编程总结

    Java线程:线程的调度-让步 Java线程:线程的调度-合并 Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作...

    Java 线程总结

    Java线程:线程的调度-让步 Java线程:线程的调度-合并 Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 ...

    java多线程笔记

    Java线程:线程的调度-让步 19 Java线程:线程的调度-合并 22 Java线程:线程的调度-终止线程 25 Java线程:线程的调度-守护线程 28 Java线程:线程组 30 Java线程:线程的同步 33 一、 同步方法 35 二、 同步块 36 ...

    java 线程让步(Yield)

    java 线程让步(Yield) java 线程让步(Yield) java 线程让步(Yield)

    Java线程让步_动力节点Java学院整理

    yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权...

    java线程文档大全

    包含java线程的概念、原理、交互、合并、让步、守护、休眠、同步、锁以及新特性 锁 线程池 信号量 有返回值的线程 原子量 障碍器 阻塞列队和阻塞栈。java开发必备参考文档。

    java中的线程让步例子.

    在最近的java学习中,写了一些小例子,都是一些常用知识,上传希望大家下载,共同学习。

    java线程学习笔记

    2.3 线程本地存储(Java.lang.ThreadLocal) 15 2.4 线程阻塞 17 2.4.1 调用sleep(millisecond)使任务进入休眠状态 17 2.4.2 等待输出与输入 17 2.4.3 对象锁不可用 17 2.4.4 通过wait()使线程挂起。 17 2.5 线程...

    详解Java中的线程让步yield()与线程休眠sleep()方法

    Java中的线程让步会让线程让出优先级,而休眠则会让线程进入阻塞状态等待被唤醒,这里我们对比线程等待的wait()方法,来详解Java中的线程让步yield()与线程休眠sleep()方法

    java基本教程之线程让步 java多线程教程

    本文对Thread中的线程让步方法yield()进行介绍,yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权,大家参考使用吧

    Java线程让步yield用法实例分析

    主要介绍了Java线程让步yield用法,结合实例形式分析了java中yield()方法的功能、原理及线程让步操作的相关实现技巧,需要的朋友可以参考下

    动力节点_Java基础视频教程216_线程-线程让步

    动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、Java的面向对象。每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础...

    BAT面试官有点懵系列,Java多线程你真的理解透彻了吗?带你玩转一次多线程!Let’s go!别再out了!

    Callable 和 Future 创建线程三种创建线程方式做出对比线程生命周期线程控制join线程后台线程线程睡眠线程让步yieId线程优先级控制线程同步的“必要性”synchronized线程同步释放同步监视器锁定Lock对象控制线程同步...

    Java线程的控制详解

    主要介绍了Java中的join线程、后台线程、线程睡眠、线程让步以及线程的优先级,非常的详细,希望能对大家有所帮助

    java7源码-scn:《疯狂Java讲义》学习

    控制线程:join线程、后台线程、线程睡眠(sleep)、线程让步(yield)、改变线程优先级 同步代码块,同步方法synchronized 同步锁:ReentrantLock锁(具有重入性) 死锁 线程通信 线程池 2.网络编程 Java的基本网络支持:...

    Java yield()线程让步实现过程解析

    主要介绍了Java yield()线程让步实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics