文章目录
- 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{}中。