java中interrupt、join、sleep、notify、notifyAll、wait详解

首先介绍一下中断概念:举个例子容易理解一点

例子:假如你正在给朋友写信,电话铃响了。这时,你放下手中的笔,去接电话。通话完毕,再继续写信。这个例子就表现了中断及其处理过程:电话铃声使你暂时中止当前的工作,而去处理更为急需处理的事情(接电话),把急需处理的事情处理完毕之后,再回头来继续原来的事情。在这个例子中,电话铃声称为“中断请求”,你暂停写信去接电话叫作“中断响应”,接电话的过程就是“中断处理”。

interrupt:中断线程

如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException

如果线程在调用 Object 类的 wait()wait(long)wait(long, int) 方法,或者该类的 join()join(long)join(long, int)sleep(long)sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException

如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException

如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。

如果以前的条件都没有保存,则该线程的中断状态将被设置。

中断一个不处于活动状态的线程不需要任何作用。

join:等待该线程终止

上传实例代码:

  1. /** 
  2.  * @author Potter  
  3.  * @version 创建时间:2011-6-30 上午09:11:32 
  4.  * 类说明:java中线程中join()是等待这个线程终止后执行后面的代码 
  5.  */  
  6.   
  7. public class JoinTest{  
  8.     public static String object="adb";  
  9.     public static void main(String[] args){  
  10.         Thread th=new Thread(new RunnableImpl());  
  11.         new  ThreadTest(th).start();// 这个线程会持有锁  
  12.         th.start();  
  13.         try {  
  14.             th.join();  
  15.             System.out.println("joinFinish");  
  16.         } catch (Exception e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.     }  
  20. }  
  21. class ThreadTest extends Thread{  
  22.     Thread thread;  
  23.     public ThreadTest(Thread thread){  
  24.         this.thread=thread;  
  25.     }  
  26.     public void run(){  
  27.         holdThreadLock();  
  28.     }  
  29.     public void holdThreadLock(){  
  30.         synchronized (JoinTest.object) {  
  31.             System.out.println("getObjectLock");  
  32.             try {  
  33.                 Thread.sleep(5000);  
  34.             } catch (Exception e) {  
  35.                 e.printStackTrace();  
  36.             }  
  37.             System.out.println("ReleaseObjectLock");  
  38.         }  
  39.     }  
  40. }  
  41.   
  42. class  RunnableImpl  implements  Runnable {  
  43.       
  44.     @Override  
  45.     public void run() {  
  46.         synchronized (JoinTest.object) {  
  47.             try {  
  48.                 System.out.println("Begin sleep");  
  49.                 Thread.sleep(2000);  
  50.                 System.out.println("End sleep");  
  51.             } catch (Exception e) {  
  52.                 e.printStackTrace();  
  53.             }  
  54.         }  
  55.     }  
  56.       
  57. }  

执行结果:

Begin sleep End sleep getObjectLock joinFinish ReleaseObjectLock

或者

getObjectLock ReleaseObjectLock Begin sleep End sleep joinFinish

原因:由于cup为实时处理,所以main线程、th线程、ThreadTest线程同时并发的,同时抢占cpu的。

sleep(long millis):在制定的毫秒数类让当前正在执行的线程暂停执行millis毫秒

在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权

notify():唤醒在此对象监视器上等待的单个线程【随机的线程】

唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。

此方法只应由作为此对象监视器的所有者的线程来调用。通过以下三种方法之一,线程可以成为此对象监视器的所有者:

  • 通过执行此对象的同步实例方法。
  • 通过执行在此对象上进行同步的 synchronized 语句的正文。
  • 对于 Class 类型的对象,可以通过执行该类的同步静态方法。

一次只能有一个线程拥有对象的监视器。

notifyAll() :唤醒在此对象监视器上等待的所有线程

唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。

此方法只应由作为此对象监视器的所有者的线程来调用。有关线程能够成为监视器所有者的方法的描述,请参阅 notify 方法。

原文地址:https://www.cnblogs.com/Free-Thinker/p/3440322.html