文章目录

  • java中断
  • 中断的意义
  • 为什么synchronized不能中断ReentrantLock能中断


java中断

概念:

Java中断机制是一种协作机制,中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。

如何中断:

java.lang.Thread类提供了几个方法来操作这个中断状态,这些方法包括:

//中断线程
   public static boolean interrupted()

   //测试当前线程是否已经中断。线程的中断状态由该方法清除。

   public boolean isInterrupted()

   //测试线程是否已经中断。线程的中断状态不受该方法的影响。

   public void interrupt()

线程1通过调用interrupt方法将线程2的中断状态置为true,可以在合适的时候调用interrupted或isInterrupted来检测状态并做相应的处理。

还有一种中断:

thread.stop():

stop方法调用线程会马上停止,但是可能导致数据不同步,或者资源得不到回收的问题而且stop已经标注为作废方法,所以使用一定要慎重。

中断的意义

  • interrupt()方法仅仅是在当前线程中打了一个停止的标识将中断标志修改为true,并没有真正的停止线程:
  • 如果在此基础上进入堵塞状态(sleep(),wait(),join()),马上就会抛出一个InterruptedException,且中断标志被清除,重新设置为false,线程退出。

中断的响应:

  • 有些程序可能一检测到中断就立马将线程终止,有些可能是退出当前执行的任务,继续执行下一个任务……
  • 作为一种协作机制,这要与中断方协商好,当调用interrupt会发生些什么都是事先知道的,如做一些事务回滚操作,一些清理工作,一些补偿操作等。
  • 若不确定调用某个线程的interrupt后该线程会做出什么样的响应,那就不应当中断该线程。

为什么synchronized不能中断ReentrantLock能中断

ReentrantLock是可中断锁,而synchronized 不是可中断锁。ReentrantLock可以获取到锁状态的。

例如:线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定

  • 如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断
  • 如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情

ReentrantLock获取锁定与三种方式:

  • a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
  • b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
  • c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
  • d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断

synchronized是在JVM层面上实现的,lock是通过代码实现的,JVM会自动释放锁定(代码执行完成或者出现异常),但是使用Lock则不行,要保证锁定一定会被释放,就必须将unLock()放到finally{}中。