Honeyc's Blog

Java多线程-Lock

Lock

ReentrantLock 类:完全互斥排它

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
// 基础示例
public class Myservice{
public void method(){
private Lock lock = new ReentrantLock();
lock.lock();
for(int i = 0; i < 5; i++){
}
lock.unlock();
}
}
public class Mythread extends Thread{
private Myservice service;
public Mythread(Myservice service){
super();
this.service = service;
}
@Override
public void run(){
service.method();
}
}
public static void main(String[] args){
Myservice service = new Myservice();
Mythread t = new Mythread(service);
t.start();
}
// 使用COndition类实现等待/通知(类似关键字synchronized与wait()和notify())
public Condition condition = lock.newCondition();
condition.await(long time , TimeUnit unit); //等待
condition.signal(); //唤醒
condition.signalAll(); //唤醒
//公平锁:表示线程获取锁的顺序是按照线程加锁的顺序来分配的
//非公平锁:随机分配
private Lock lock = new ReentrantLock(true/false);
//API
int getHoldCount() : 当前线程调用lock()方法的次数
int getQueueLength() : 返回正等待获取锁定的线程估计数
int getWaitQueueLength(Condition cond):返回当前等待与此锁定相关的给定条件Condition的线程估计数。
boolean hasQueuedThread(thread);

生产者/消费者模式-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
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
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @功能:使用Lock Conditon
* @作者: honeycc
* @时间:2016-12-29
* @版本:1.0
*/
public class TestLock {
public static Lock lock = new ReentrantLock();;
// 容器已满 綁定product線程
public static Condition full = lock.newCondition();
// 容器为空 綁定consumer線程
public static Condition empty = lock.newCondition();
public static void main(String[] args) {
List list = new ArrayList(12);
Product product = new Product(list, 10);
Consumer consumer = new Consumer(list, 0);
Thread t1 = new Thread(product);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
// 生产
static class Product implements Runnable {
private List list;
private int maxCount;
public Product(List list, int maxCount) {
super();
this.list = list;
this.maxCount = maxCount;
}
@Override
public void run() {
while(true){
if (lock.tryLock()) {
try {
if (getSize() >= maxCount) {
System.out.println("容器已滿,product線程加入池中...");
full.await();
}
System.out.println("開始生產....");
list.add(new Object());
//喚醒消費者線程
empty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} else {
System.out.println("未获取生产资格...");
}
}
}
public int getSize() {
return list.size();
}
}
// 消费
static class Consumer implements Runnable {
private List list;
private int minCount;
public Consumer(List list, int minCount) {
super();
this.list = list;
this.minCount = minCount;
}
@Override
public void run() {
while(true){
if (lock.tryLock()) {
try {
if (getSize() <= minCount) {
System.out.println("容器已空,consumer線程加入池中...");
empty.await();
}
System.out.println("開始消費....");
list.remove(0);
//喚醒生產者線程
full.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} else {
System.out.println("未获取消费资格...");
}
}
}
public int getSize() {
return list.size();
}
}
}

ReentrantReadWriteLock 类:使用两把锁,一个读锁(共享锁),一个写锁(排它锁)

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
// 读读共享
public class Service{
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read(){
try{
try{
lock.readLock().lock();
System.out.print("aaa");
Thread.sleep(10000);
}finally{
lock.readLock().unlock();
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//写写互斥
public class Service{
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write(){
try{
try{
lock.writeLock().lock();
System.out.print("aaa");
Thread.sleep(10000);
}finally{
lock.writeLock().unlock();
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//读写-写读-互斥
public class Service{
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write(){
try{
try{
lock.writeLock().lock();
System.out.print("aaa");
Thread.sleep(10000);
}finally{
lock.writeLock().unlock();
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
public void read(){
try{
try{
lock.writeLock().lock();
System.out.print("aaa");
Thread.sleep(10000);
}finally{
lock.writeLock().unlock();
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}