ReentrantLock是JDK唯一实现了Lock接口的类
lock()
是平常使用得最多的一个方法,就是用来获取锁。如果锁已被其他线程获取,则进行等待。
由于在前面讲到如果采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁。因此一般来说,使用Lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。
实例
各自独立的Lock对象
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@Test public void testLock1() { // 两个线程的lock对象是彼此独立,没有任何关系,没有起到锁的作用 new Thread() { @Override public void run() { Lock lock = new ReentrantLock(); String tName=Thread.currentThread().getName(); System.out.println(tName+"还没有锁,开始主动获取锁......"); lock.lock();// 主动获取锁 System.out.println(tName+"获取到锁!"); try { int n = 1 / 0; System.out.println(n); for (int i = 0; i < 10; i++) { System.out.println(tName+":" + i); } } catch (Exception e) { System.out.println(tName+"出错了!!!"); }finally { //lock.unlock(); } } }.start(); new Thread() { @Override public void run() { Lock lock = new ReentrantLock(); String tName=Thread.currentThread().getName(); System.out.println(tName+"还没有锁,开始主动获取锁......"); lock.lock();// 主动获取锁,此时获取不到锁,因为线程1出错了,lock()不会主动释放锁,线程1又没有释放锁,所以就死锁了。 System.out.println(tName+"tName获取到锁!"); for (int i = 0; i < 10; i++) { System.out.println(tName+":" + i); } } }.start(); }
运行结果:
Thread-0还没有锁,开始主动获取锁......
Thread-0获取到锁!
Thread-0出错了!!!
Thread-1还没有锁,开始主动获取锁......
Thread-1tName获取到锁!
Thread-1:0
Thread-1:1
Thread-1:2
Thread-1:3
Thread-1:4
Thread-1:5
Thread-1:6
Thread-1:7
Thread-1:8
Thread-1:9
锁对象是同一个
两个线程的锁对象是同一个,当获取锁的线程没有释放锁的时候,就产生了死锁,其他线程只能无止尽地等待
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@Test public void testLock2() { //两个线程的锁对象是同一个,当获取锁的线程没有释放锁的时候,就产生了死锁,其他线程只能无止尽地等待 Lock lock = new ReentrantLock(); new Thread() { @Override public void run() { String tName=Thread.currentThread().getName(); System.out.println(tName+"还没有锁,开始主动获取锁......"); lock.lock();// 主动获取锁 System.out.println(tName+"获取到锁!"); try { int n = 1 / 0; System.out.println(n); for (int i = 0; i < 10; i++) { System.out.println(tName+":" + i); } } catch (Exception e) { System.out.println(tName+"出错了!!!"); }finally { } } }.start(); new Thread() { @Override public void run() { String tName=Thread.currentThread().getName(); System.out.println(tName+"还没有锁,开始主动获取锁......"); lock.lock();// 主动获取锁,此时获取不到锁,因为之前出错了,lock()不会主动释放锁,线程又没有释放锁,所以就死锁了。 System.out.println(tName+"tName获取到锁!"); for (int i = 0; i < 10; i++) { System.out.println(tName+":" + i); } } }.start(); }
Thread-0还没有锁,开始主动获取锁......
Thread-0获取到锁!
Thread-0出错了!!!
Thread-1还没有锁,开始主动获取锁......
释放锁
两个线程的锁对象是同一个,当获取锁的线程没有释放锁的时候,就产生了死锁,其他线程只能无止尽地等待
在try-finally里不管是顺利执行完,还是出错,都要主动释放锁,则其他线程就能获取到
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@Test public void testLock3() { //两个线程的锁对象是同一个,当获取锁的线程没有释放锁的时候,就产生了死锁,其他线程只能无止尽地等待 //在try-finally里不管是顺利执行完,还是出错,都要主动释放锁,则其他线程就能获取到 Lock lock = new ReentrantLock(); new Thread() { @Override public void run() { String tName=Thread.currentThread().getName(); System.out.println(tName+"还没有锁,开始主动获取锁......"); lock.lock();// 主动获取锁 System.out.println(tName+"获取到锁!"); try { int n = 1 / 0; System.out.println(n); for (int i = 0; i < 10; i++) { System.out.println(tName+":" + i); } } catch (Exception e) { System.out.println(tName+"出错了!!!"); }finally { System.out.println(tName+"释放锁!!"); lock.unlock(); } } }.start(); new Thread() { @Override public void run() { String tName=Thread.currentThread().getName(); System.out.println(tName+"还没有锁,开始主动获取锁......"); lock.lock();// 主动获取锁,此时获取不到锁,因为之前出错了,lock()不会主动释放锁,线程又没有释放锁,所以就死锁了。 System.out.println(tName+"tName获取到锁!"); for (int i = 0; i < 10; i++) { System.out.println(tName+":" + i); } } }.start(); }
Thread-0还没有锁,开始主动获取锁......
Thread-0获取到锁!
Thread-0出错了!!!
Thread-0释放锁!!
Thread-1还没有锁,开始主动获取锁......
Thread-1tName获取到锁!
Thread-1:0
Thread-1:1
Thread-1:2
Thread-1:3
Thread-1:4
Thread-1:5
Thread-1:6
Thread-1:7
Thread-1:8
Thread-1:9
最后
以上就是美好樱桃最近收集整理的关于Lock的lock()方法lock()实例的全部内容,更多相关Lock内容请搜索靠谱客的其他文章。
发表评论 取消回复