博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lock应用之 可中断
阅读量:6654 次
发布时间:2019-06-25

本文共 5880 字,大约阅读时间需要 19 分钟。

Thread.interrupt()方法可用于中断指定线程,但线程并不是在任何状态下可被立即中断,一般只有当线程处于阻塞状态(调用wait(),join(),sleep()等方法)时才会被立即中断,如果线程处于不可被立即中断状态,那么Thread.interrupt()只会标志线程的中断状态,以便后续操作用于判断,即isInterrupted()方法会返回true.

线程等待获取内部锁的时候,是一种不可立即中断状态,即线程不会立即响应中断而是会继续等待,这种无义无反顾的等待可能会造成资源浪费或者死锁等问题,后果非常严重。新Lock锁提供了等待锁资源时可立即响应中断的lockInterruptibly()方法和tryLock(long time, TimeUnit unit)方法及其实现,当使用这两个方法去请求锁时,如果主通过Thread.interrupt()对它们发起中断,那么它们会立即响应中断,不再继续等待获取锁,这让主线程(管理调度线程)在特殊情况下可以使用生杀大权,以避免系统陷于死锁状态或者避免资源严重浪费。

tryLock(long time, TimeUnit unit)是加强版的tryLock(),又具有lockInterruptibly()的可被中断特性,既可任其超时主动退出又可中断让其被动退出,很多场合可以使用,但如果想让线程只有当被动中断时才退出,那么就使用lockInterruptibly()方法。

通过测试可以得出以下结论:

  • 内部锁(synchronized) 优先响应锁获取再响应中断

  • Lock.lock() 优先响应锁获取再响应中断

  • Lock.tryLock() 判断锁的状态不可用后马上返回不等待

  • tryLock(long time, TimeUnit unit) 优先响应中断再响应锁获取

  • Lock.lockInterruptibly() 优先响应中断再响应锁获取

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import 
java.util.concurrent.TimeUnit;
import 
java.util.concurrent.locks.Lock;
import 
java.util.concurrent.locks.ReentrantLock;
public 
class 
TestLockInterrupt {
    
private 
Lock mLock1;
    
private 
Lock mLock2;
    
private 
Lock mLock3;
                                                                                                                                                  
    
public 
TestLockInterrupt(){
        
mLock1 = 
new 
ReentrantLock();
        
mLock2 = 
new 
ReentrantLock();
        
mLock3 = 
new 
ReentrantLock();  
    
}
                                                                                                                                                  
    
public 
void 
f(){
        
System.out.println(Thread.currentThread().getName() + 
":try to get lock in f()."
);
                                                                                                                                                      
        
try
{
            
synchronized
(
this
){
                
System.out.println(Thread.currentThread().getName() + 
":get the lock."
);
                                                                                                                                                              
                
if
(Thread.currentThread().isInterrupted()){
                    
System.out.println(Thread.currentThread().getName() + 
":already marked as interrupted but still running."
);
                
}
                                                                                                                                                              
                
TimeUnit.SECONDS.sleep(
100
);
            
}
                                                                                                                                                          
            
System.out.println(Thread.currentThread().getName() + 
":release the lock."
);
        
}
        
catch
(InterruptedException e){
            
System.out.println(Thread.currentThread().getName() + 
":interrupted."
);
        
}          
    
}
                                                                                                                                                  
    
public 
void 
fWithLock(){
        
System.out.println(Thread.currentThread().getName() + 
":try to get lock in fWithLock()."
);
                                                                                                                                                      
        
mLock1.lock();
        
try
{
            
System.out.println(Thread.currentThread().getName() + 
":get the lock."
);
                                                                                                                                                          
            
if
(Thread.currentThread().isInterrupted()){
                
System.out.println(Thread.currentThread().getName() + 
":already marked as interrupted but still running."
);
            
}
                                                                                                                                                          
            
TimeUnit.SECONDS.sleep(
100
);
        
}
        
catch
(InterruptedException e){
            
System.out.println(Thread.currentThread().getName() + 
":interrupted."
);
        
}
        
finally
{
            
mLock1.unlock();
            
System.out.println(Thread.currentThread().getName() + 
":release the lock."
);
        
}          
    
}
                                                                                                                                                  
    
public 
void 
fWithTryLock(){
        
System.out.println(Thread.currentThread().getName() + 
":try to get lock in fWithTryLock()."
);
                                                                                                                                                              
        
try
{
            
if
(mLock2.tryLock(
50
, TimeUnit.SECONDS)){
                
try
{
                    
System.out.println(Thread.currentThread().getName() + 
":get the lock."
);
                                                                                                                                                                  
                    
if
(Thread.currentThread().isInterrupted()){
                        
System.out.println(Thread.currentThread().getName() + 
":already marked as interrupted but still running."
);
                    
}
                                                                                                                                                                  
                    
TimeUnit.SECONDS.sleep(
100
);
                
}
                
finally
{
                    
mLock2.unlock();
                    
System.out.println(Thread.currentThread().getName() + 
":release the lock."
);
                
}
            
}      
        
}
        
catch
(InterruptedException e){
            
System.out.println(Thread.currentThread().getName() + 
":interrupted."
);
        
}                  
    
}
                                                                                                                                                  
    
public 
void 
fWithLockInterruptibly(){
        
System.out.println(Thread.currentThread().getName() + 
":try to get lock in fWithLockInterruptibly()."
);
                                                                                                                                                      
        
try
{       
            
mLock3.lockInterruptibly();
            
System.out.println(Thread.currentThread().getName() + 
":get the lock."
);
                                                                                                                                                          
            
try
{
                
if
(Thread.currentThread().isInterrupted()){
                    
System.out.println(Thread.currentThread().getName() + 
":already marked as interrupted but still running."
);
                
}
                                                                                                                                                              
                
TimeUnit.SECONDS.sleep(
100
);
            
}
            
finally
{
                
mLock3.unlock();
                
System.out.println(Thread.currentThread().getName() + 
":release the lock."
);
            
}      
        
}
        
catch
(InterruptedException e){
            
System.out.println(Thread.currentThread().getName() + 
":interrupted."
);
        
}          
    
}
    
private 
class 
Worker 
implements 
Runnable{
        
private 
int 
index;
                                                                                                                                                      
        
public 
Worker(
int 
index){
            
this
.index = index;
        
}
                                                                                                                                                      
        
@Override
        
public 
void 
run() {
            
switch
(index){
            
case 
1
:
                
f();
                
break
;
            
case 
2
:
                
fWithLock();
                
break
;
            
case 
3
:
                
fWithTryLock();
                
break
;
            
case 
4
:
                
fWithLockInterruptibly();
                
break
;
            
}
        
}  
    
}
                                                                                                                                                  
    
public 
static 
void 
main(String[] args) {
        
TestLockInterrupt testLockInterrupt = 
new 
TestLockInterrupt();
                                                                                                                                                      
        
for
(
int 
i=
1
; i<=
4
; i++){
            
Thread t1 = 
new 
Thread(testLockInterrupt.
new 
Worker(i));
            
Thread t2 = 
new 
Thread(testLockInterrupt.
new 
Worker(i));
                                                                                                                                                          
            
t1.start();
            
t2.start();
                                                                                                                                                          
            
t1.interrupt();
            
t2.interrupt();
        
}  
    
}
}

代码输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Thread-
0
:
try 
to 
get 
lock 
in 
f().
Thread-
1
:
try 
to 
get 
lock 
in 
f().
Thread-
1
:
get 
the lock.
Thread-
3
:
try 
to 
get 
lock 
in 
fWithLock().
Thread-
1
:already marked 
as 
interrupted but still running.
Thread-
3
:
get 
the lock.
Thread-
3
:already marked 
as 
interrupted but still running.
Thread-
7
:
try 
to 
get 
lock 
in 
fWithLockInterruptibly().
Thread-
2
:
try 
to 
get 
lock 
in 
fWithLock().
Thread-
1
:interrupted.
Thread-
7
:interrupted.
Thread-
3
:interrupted.
Thread-
3
:release the lock.
Thread-
2
:
get 
the lock.
Thread-
2
:already marked 
as 
interrupted but still running.
Thread-
2
:interrupted.
Thread-
2
:release the lock.
Thread-
4
:
try 
to 
get 
lock 
in 
fWithTryLock().
Thread-
4
:interrupted.
Thread-
0
:
get 
the lock.
Thread-
0
:already marked 
as 
interrupted but still running.
Thread-
0
:interrupted.
Thread-
5
:
try 
to 
get 
lock 
in 
fWithTryLock().
Thread-
5
:interrupted.
Thread-
6
:
try 
to 
get 
lock 
in 
fWithLockInterruptibly().
Thread-
6
:interrupted.
     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1301184,如需转载请自行联系原作者
你可能感兴趣的文章
make[4]: Entering directory `/home/li/tools/mysql-5.1.72/mysql-test'
查看>>
你,需要时(zi)间(wo)管理
查看>>
[玩系列教程]x版本更改用戶名方法
查看>>
记录一次服务器被***
查看>>
模板机部署系统后的eth0网卡设置
查看>>
Protocol Numbers 协议号文档
查看>>
为什么php的trait不能实现interface
查看>>
【Weblogic干货】瞬间运行正常的weblogic.xml内幕
查看>>
SUSE FTP问题
查看>>
JNCIS翻译文档之------接口
查看>>
Linux mint 16与win7双系统引导
查看>>
Java初学者习题20道
查看>>
23种基本设计模式
查看>>
JRE+MYSQL+JETTY安装部署
查看>>
想自由
查看>>
mysql的json特性的应用
查看>>
(转)virtualbox 与宿主交换剪贴板的问题
查看>>
我的友情链接
查看>>
Minimum Transport Cost (floyd算法)
查看>>
我的友情链接
查看>>