ReentrantLock常见使用
Lock接口:
ReentrantLock的基本功能:
ReentrantLock的lock和unlock方法进行加锁,解锁。可以起到和synchronized关键字一样的效果;
选择性通知!!!:
使用Condition实现等待通知,和wait/notifyAll机制一样,要使用await()方法进入WAITING状态,就必须要先使用lock.lock()获得同步监视器。
1 package service;
2
3 import java.util.concurrent.locks.Condition;
4 import java.util.concurrent.locks.ReentrantLock;
5
6 public class MyService {
7 private ReentrantLock lock = new ReentrantLock();
8 private Condition condition = lock.newCondition();
9
10 public void waitMethod() {
11 try {
12 lock.lock();
13 System.out.println("A");
14 condition.await();
15 System.out.println("B");
16 } catch (InterruptedException e) {
17 e.printStackTrace();
18 } finally {
19 lock.unlock();
20 System.out.println("锁释放了!");
21 }
22 }
23 }
View Code
类比wait/notify机制:wait-->await notify-->signal notifyAll-->signalAll
选择性通知:使用多个Condition实现
package service;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock = new ReentrantLock();
// 使用多个Condition todo 查看原理
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();
public void awaitA() {
try {
lock.lock();
System.out.println("begin awaitA时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionA.await();
System.out.println(" end awaitA时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void awaitB() {
try {
lock.lock();
System.out.println("begin awaitB时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionB.await();
System.out.println(" end awaitB时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signalAll_A() {
try {
lock.lock();
System.out.println(" signalAll_A时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionA.signalAll();
} finally {
lock.unlock();
}
}
public void signalAll_B() {
try {
lock.lock();
System.out.println(" signalAll_B时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionB.signalAll();
} finally {
lock.unlock();
}
}
}
View Code
public ReentrantLock(true) 采用公平策略。反之采用不公平策略。
tryLock():如果没被锁定,获得锁。否则不获得锁。
tryLock(long timeout , TimeUnit unit):给宽定时间的tryLock()
1 package service;
2
3 import java.util.concurrent.locks.ReentrantLock;
4
5 public class MyService {
6
7 public ReentrantLock lock = new ReentrantLock();
8
9 public void waitMethod() {
10 if (lock.tryLock()) {
11 System.out.println(Thread.currentThread().getName() + "获得锁");
12 } else {
13 System.out.println(Thread.currentThread().getName() + "没有获得锁");
14 }
15 }
16 }
View Code
1 package service;
2
3 import java.util.concurrent.TimeUnit;
4 import java.util.concurrent.locks.ReentrantLock;
5
6 public class MyService {
7
8 public ReentrantLock lock = new ReentrantLock();
9
10 public void waitMethod() {
11 try {
12 if (lock.tryLock(3, TimeUnit.SECONDS)) {
13 System.out.println(" " + Thread.currentThread().getName()
14 + "获得锁的时间:" + System.currentTimeMillis());
15 Thread.sleep(10000);
16 } else {
17 System.out.println(" " + Thread.currentThread().getName()
18 + "没有获得锁");
19 }
20 } catch (InterruptedException e) {
21 e.printStackTrace();
22 } finally {
23 if (lock.isHeldByCurrentThread()) {
24 lock.unlock();
25 }
26 }
27 }
28 }
View Code
使用Codition实现顺序执行
1 package test.run;
2
3 import java.util.concurrent.locks.Condition;
4 import java.util.concurrent.locks.ReentrantLock;
5
6 public class Run {
7
8 volatile private static int nextPrintWho = 1;
9 private static ReentrantLock lock = new ReentrantLock();
10 final private static Condition conditionA = lock.newCondition();
11 final private static Condition conditionB = lock.newCondition();
12 final private static Condition conditionC = lock.newCondition();
13
14 public static void main(String[] args) {
15
16 Thread threadA = new Thread() {
17 public void run() {
18 try {
19 lock.lock();
20 while (nextPrintWho != 1) {
21 conditionA.await();
22 }
23 for (int i = 0; i < 3; i++) {
24 System.out.println("ThreadA " + (i + 1));
25 }
26 nextPrintWho = 2;
27 conditionB.signalAll();
28 } catch (InterruptedException e) {
29 e.printStackTrace();
30 } finally {
31 lock.unlock();
32 }
33 }
34 };
35
36 Thread threadB = new Thread() {
37 public void run() {
38 try {
39 lock.lock();
40 while (nextPrintWho != 2) {
41 conditionB.await();
42 }
43 for (int i = 0; i < 3; i++) {
44 System.out.println("ThreadB " + (i + 1));
45 }
46 nextPrintWho = 3;
47 conditionC.signalAll();
48 } catch (InterruptedException e) {
49 e.printStackTrace();
50 } finally {
51 lock.unlock();
52 }
53 }
54 };
55
56 Thread threadC = new Thread() {
57 public void run() {
58 try {
59 lock.lock();
60 while (nextPrintWho != 3) {
61 conditionC.await();
62 }
63 for (int i = 0; i < 3; i++) {
64 System.out.println("ThreadC " + (i + 1));
65 }
66 nextPrintWho = 1;
67 conditionA.signalAll();
68 } catch (InterruptedException e) {
69 e.printStackTrace();
70 } finally {
71 lock.unlock();
72 }
73 }
74 };
75 Thread[] aArray = new Thread[5];
76 Thread[] bArray = new Thread[5];
77 Thread[] cArray = new Thread[5];
78
79 for (int i = 0; i < 5; i++) {
80 aArray[i] = new Thread(threadA);
81 bArray[i] = new Thread(threadB);
82 cArray[i] = new Thread(threadC);
83
84 aArray[i].start();
85 bArray[i].start();
86 cArray[i].start();
87 }
88
89 }
90 }
View Code
ReentrantReadWriteLock:
出现目的:ReentrantLock完全互斥排他,效率低下。
改善:ReentrantReadWriteLock 读写锁。只要有写操作就是互斥的,没有写操作,就是共享的。
1 package service;
2
3 import java.util.concurrent.locks.ReentrantReadWriteLock;
4
5
6 /*
7 output:时间差为10000
8
9 */
10
11 public class Service {
12
13 private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
14
15 public void read() {
16 try {
17 try {
18 lock.readLock().lock();
19 System.out.println("获得读锁" + Thread.currentThread().getName()
20 + " " + System.currentTimeMillis());
21 Thread.sleep(10000);
22 } finally {
23 lock.readLock().unlock();
24 }
25 } catch (InterruptedException e) {
26 e.printStackTrace();
27 }
28 }
29
30 public void write() {
31 try {
32 try {
33 lock.writeLock().lock();
34 System.out.println("获得写锁" + Thread.currentThread().getName()
35 + " " + System.currentTimeMillis());
36 Thread.sleep(10000);
37 } finally {
38 lock.writeLock().unlock();
39 }
40 } catch (InterruptedException e) {
41 e.printStackTrace();
42 }
43 }
44
45 }
View Code