ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

聊聊Lock接口的lock()和lockInterruptible()有什么区别?

2021-05-03 21:02:14  阅读:127  来源: 互联网

标签:Thread 中断 Lock lockInterruptible t1 获取 lock 等待


lock()和lockInterruptible()都表示获取锁,唯一区别是,当A线程调用lock()方法获取锁没有成功而进入等待锁的状态时,若接着调用该A线程的interrupt()方法中断该线程的等待:
  • 如果A线程是通过lock()获取锁失败而进入等待状态的:则A线程不会马上执行自己的interrupt()方法去中断等待,而是继续等待获取锁(同时把中断命令放入等待队列), 获取到锁之后才响应自己的interrupt()方法去中断等待(从等待丢列中拿出中断命令执行)。获取锁之后,若A线程没有处于等待状态而调用interrupt()方法,是不会发生任何事情的,若获取锁之后A刚刚好又进入了等待状态,则执行等待丢列中的中断命令就会让A抛出InterruptedException()异常去中断等待
  • 如果A线程是想通过lockInterruptible()获取锁失败而进入等待状态的:则A线程会马上响应自己的interrupt()方法抛出InterruptedException 异常去中断等待,此时在finally里处理该异常,从而接着执行其他的代码

使用lockInterruptible()获取锁的例子:

 1  2 public class LockTest {
 3     private Lock lock = new ReentrantLock();
 4     public void doBussiness() {
 5         String name = Thread.currentThread().getName();
 6  
 7         try {
 8             System.out.println(name + " 开始获取锁");
 9             lock.lockInterruptibly();//获取锁,可以调interrupt()中断等待
10             System.out.println(name + " 得到锁");
11             System.out.println(name + " 开工干活");
12             for (int i=0; i<5; i++) {
13                 Thread.sleep(1000);
14                 System.out.println(name + " : " + i);
15             }
16         } catch (InterruptedException e) {
17             //用lockInterruptibly()获取锁,必须处理可能调用interrupt()而抛出的InterruptedException异常
18             System.out.println(name + " 被中断");
19             System.out.println(name + " 做些别的事情");
20         } finally {
21             try {
22                 lock.unlock();
23                 System.out.println(name + " 释放锁");
24             } catch (Exception e) {
25                 System.out.println(name + " : 没有得到锁的线程运行结束");
26             }
27         }
28     }
29  
30     public static void main(String[] args) throws InterruptedException {
31  
32         LockTest lockTest = new LockTest();
33  
34         Thread t0 = new Thread(
35                 new Runnable() {
36                     public void run() {
37                         lockTest.doBussiness();
38                     }
39                 }
40                 );
41  
42         Thread t1 = new Thread(
43                 new Runnable() {
44                     public void run() {
45                         lockTest.doBussiness();
46                     }
47                 }
48                 );
49  
50         // 启动线程t1
51         t0.start();
52         Thread.sleep(10);
53         // 启动线程t2
54         t1.start();
55         Thread.sleep(100);
56         // 线程t1没有得到锁,中断t1的等待
57         t1.interrupt();
58     }
59 }
60 #运行结果:
61 Thread-0 开始获取锁
62 Thread-0 得到锁
63 Thread-0 开工干活
64 Thread-1 开始获取锁
65 Thread-1 被中断  //线程t1用lockInterruptible()获取锁失败而进入等待时,主线程调用t1.interrupt()使该t1抛出异常从而中断等待
66 Thread-1 做些别的事情//t1中断等待后接着执行其他的代码
67 Thread-1 : 没有得到锁的线程运行结束
68 Thread-0 : 0
69 Thread-0 : 1
70 Thread-0 : 2
71 Thread-0 : 3
72 Thread-0 : 4
73 Thread-0 释放锁

使用lock()获取锁的例子:

 1 把上面第9行中lock.lockInterruptibly()改为lock.lock(),其他代码不变,则输出结果:
 2 
 3 Thread-0 开始获取锁
 4 Thread-0 得到锁
 5 Thread-0 开工干活
 6 Thread-1 开始获取锁  //t0已经获取到了锁,所以t1只能进入等待状态(线程没有获取到锁会进入等待状态)。因为t1是调用lock.lock()获取锁的,所以即便主线程调用t1.interrupt()方法,t1也不会马上响应中断(即抛出InterruptedException异常来中断自己的等待状态),而是直到拿到锁之后才会响应中断
 7 Thread-0 : 0
 8 Thread-0 : 1
 9 Thread-0 : 2
10 Thread-0 : 3
11 Thread-0 : 4  
12 Thread-1 得到锁  //t0打印完后已经执行了lock.unlock()释放了锁,要不然t1是拿不到锁的。同时t0还没来得及执行上面第23行代码用System打印出“Thread-0 释放锁”,时间片就轮给了t1,所以这行代码是t1执行输出的
13 Thread-1 开工干活
14 Thread-1 被中断 //由于t1拿到锁后才会去响应中断,所以上面第13行Thread.sleep(1000)在t1拿到锁之后又让t1进入了等待状态,此时t1刚刚好执行响应中断,故抛出InterruptedException异常来响应中断
15 Thread-1 做些别的事情
16 Thread-0 释放锁
17 Thread-1 释放锁  //t0早就释放了锁,在这里重新获得了时间片进行打印操作

 

标签:Thread,中断,Lock,lockInterruptible,t1,获取,lock,等待
来源: https://www.cnblogs.com/afei1759/p/14728144.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有