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
<code>import</code> <code>java.util.concurrent.TimeUnit;</code>
<code>import</code> <code>java.util.concurrent.locks.Lock;</code>
<code>import</code> <code>java.util.concurrent.locks.ReentrantLock;</code>
<code>public</code> <code>class</code> <code>TestLockInterrupt {</code>
<code> </code><code>private</code> <code>Lock mLock1;</code>
<code> </code><code>private</code> <code>Lock mLock2;</code>
<code> </code><code>private</code> <code>Lock mLock3;</code>
<code> </code>
<code> </code><code>public</code> <code>TestLockInterrupt(){</code>
<code> </code><code>mLock1 = </code><code>new</code> <code>ReentrantLock();</code>
<code> </code><code>mLock2 = </code><code>new</code> <code>ReentrantLock();</code>
<code> </code><code>mLock3 = </code><code>new</code> <code>ReentrantLock(); </code>
<code> </code><code>}</code>
<code> </code><code>public</code> <code>void</code> <code>f(){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":try to get lock in f()."</code><code>);</code>
<code> </code>
<code> </code><code>try</code><code>{</code>
<code> </code><code>synchronized</code><code>(</code><code>this</code><code>){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":get the lock."</code><code>);</code>
<code> </code>
<code> </code><code>if</code><code>(Thread.currentThread().isInterrupted()){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":already marked as interrupted but still running."</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>TimeUnit.SECONDS.sleep(</code><code>100</code><code>);</code>
<code> </code><code>}</code>
<code> </code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":release the lock."</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>catch</code><code>(InterruptedException e){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":interrupted."</code><code>);</code>
<code> </code><code>} </code>
<code> </code><code>public</code> <code>void</code> <code>fWithLock(){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":try to get lock in fWithLock()."</code><code>);</code>
<code> </code><code>mLock1.lock();</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":get the lock."</code><code>);</code>
<code> </code><code>if</code><code>(Thread.currentThread().isInterrupted()){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":already marked as interrupted but still running."</code><code>);</code>
<code> </code><code>TimeUnit.SECONDS.sleep(</code><code>100</code><code>);</code>
<code> </code><code>finally</code><code>{</code>
<code> </code><code>mLock1.unlock();</code>
<code> </code><code>public</code> <code>void</code> <code>fWithTryLock(){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":try to get lock in fWithTryLock()."</code><code>);</code>
<code> </code><code>if</code><code>(mLock2.tryLock(</code><code>50</code><code>, TimeUnit.SECONDS)){</code>
<code> </code><code>try</code><code>{</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":get the lock."</code><code>);</code>
<code> </code>
<code> </code><code>if</code><code>(Thread.currentThread().isInterrupted()){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":already marked as interrupted but still running."</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>TimeUnit.SECONDS.sleep(</code><code>100</code><code>);</code>
<code> </code><code>finally</code><code>{</code>
<code> </code><code>mLock2.unlock();</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":release the lock."</code><code>);</code>
<code> </code><code>} </code>
<code> </code><code>} </code>
<code> </code><code>public</code> <code>void</code> <code>fWithLockInterruptibly(){</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":try to get lock in fWithLockInterruptibly()."</code><code>);</code>
<code> </code><code>try</code><code>{ </code>
<code> </code><code>mLock3.lockInterruptibly();</code>
<code> </code><code>try</code><code>{</code>
<code> </code><code>finally</code><code>{</code>
<code> </code><code>mLock3.unlock();</code>
<code> </code><code>System.out.println(Thread.currentThread().getName() + </code><code>":release the lock."</code><code>);</code>
<code> </code><code>private</code> <code>class</code> <code>Worker </code><code>implements</code> <code>Runnable{</code>
<code> </code><code>private</code> <code>int</code> <code>index;</code>
<code> </code><code>public</code> <code>Worker(</code><code>int</code> <code>index){</code>
<code> </code><code>this</code><code>.index = index;</code>
<code> </code><code>@Override</code>
<code> </code><code>public</code> <code>void</code> <code>run() {</code>
<code> </code><code>switch</code><code>(index){</code>
<code> </code><code>case</code> <code>1</code><code>:</code>
<code> </code><code>f();</code>
<code> </code><code>break</code><code>;</code>
<code> </code><code>case</code> <code>2</code><code>:</code>
<code> </code><code>fWithLock();</code>
<code> </code><code>case</code> <code>3</code><code>:</code>
<code> </code><code>fWithTryLock();</code>
<code> </code><code>case</code> <code>4</code><code>:</code>
<code> </code><code>fWithLockInterruptibly();</code>
<code> </code><code>} </code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code>
<code> </code><code>TestLockInterrupt testLockInterrupt = </code><code>new</code> <code>TestLockInterrupt();</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>i=</code><code>1</code><code>; i<=</code><code>4</code><code>; i++){</code>
<code> </code><code>Thread t1 = </code><code>new</code> <code>Thread(testLockInterrupt.</code><code>new</code> <code>Worker(i));</code>
<code> </code><code>Thread t2 = </code><code>new</code> <code>Thread(testLockInterrupt.</code><code>new</code> <code>Worker(i));</code>
<code> </code><code>t1.start();</code>
<code> </code><code>t2.start();</code>
<code> </code><code>t1.interrupt();</code>
<code> </code><code>t2.interrupt();</code>
<code>}</code>
代码输出结果:
<code>Thread-</code><code>0</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>f().</code>
<code>Thread-</code><code>1</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>f().</code>
<code>Thread-</code><code>1</code><code>:</code><code>get</code> <code>the lock.</code>
<code>Thread-</code><code>3</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>fWithLock().</code>
<code>Thread-</code><code>1</code><code>:already marked </code><code>as</code> <code>interrupted but still running.</code>
<code>Thread-</code><code>3</code><code>:</code><code>get</code> <code>the lock.</code>
<code>Thread-</code><code>3</code><code>:already marked </code><code>as</code> <code>interrupted but still running.</code>
<code>Thread-</code><code>7</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>fWithLockInterruptibly().</code>
<code>Thread-</code><code>2</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>fWithLock().</code>
<code>Thread-</code><code>1</code><code>:interrupted.</code>
<code>Thread-</code><code>7</code><code>:interrupted.</code>
<code>Thread-</code><code>3</code><code>:interrupted.</code>
<code>Thread-</code><code>3</code><code>:release the lock.</code>
<code>Thread-</code><code>2</code><code>:</code><code>get</code> <code>the lock.</code>
<code>Thread-</code><code>2</code><code>:already marked </code><code>as</code> <code>interrupted but still running.</code>
<code>Thread-</code><code>2</code><code>:interrupted.</code>
<code>Thread-</code><code>2</code><code>:release the lock.</code>
<code>Thread-</code><code>4</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>fWithTryLock().</code>
<code>Thread-</code><code>4</code><code>:interrupted.</code>
<code>Thread-</code><code>0</code><code>:</code><code>get</code> <code>the lock.</code>
<code>Thread-</code><code>0</code><code>:already marked </code><code>as</code> <code>interrupted but still running.</code>
<code>Thread-</code><code>0</code><code>:interrupted.</code>
<code>Thread-</code><code>5</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>fWithTryLock().</code>
<code>Thread-</code><code>5</code><code>:interrupted.</code>
<code>Thread-</code><code>6</code><code>:</code><code>try</code> <code>to </code><code>get</code> <code>lock </code><code>in</code> <code>fWithLockInterruptibly().</code>
<code>Thread-</code><code>6</code><code>:interrupted.</code>
<code></code>
本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1301184,如需转载请自行联系原作者