目标:ReenTrantLock的基本功能练习
功能练习:
- 上锁、解锁
- 中断
- 条件信号
代码:
package com.miracle.study.syn;
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Miracle
* @date 2021/4/12 22:28
*/
public class ProducerCustomerTest {
/**
* 最大滞留数据
*/
private final int max;
/**
* 数据队列
*/
private LinkedList<Integer> queue;
/**
* 随机数工具
*/
private static final Random RANDOM = new Random();
/**
* 锁工具
*/
private final ReentrantLock reentrantLock = new ReentrantLock();
/**
* 队列数据为空时的线程信号
*/
private final Condition empty = reentrantLock.newCondition();
/**
* 队列数据为满时的线程信号
*/
private final Condition full = reentrantLock.newCondition();
public ProducerCustomerTest(int max){
this.max = max;
this.queue = new LinkedList<>();
}
/**
* 模拟业务函数
* @return
* @throws InterruptedException
*/
public int doSomething() throws InterruptedException {
var data = RANDOM.nextInt(100);
Thread.sleep(data);
return data;
}
/**
* 生产者
* @throws InterruptedException
*/
public void producer() throws InterruptedException {
reentrantLock.lock();
try{
// 判断队列是否为空
if (queue.size() == max){
// 生产者线程进入等待的信号
full.await();
return;
}
// 判断队列是否已经有数据可处理
if (queue.size() == 1){
// 消费者线程唤醒的信号
empty.signalAll();
}
queue.add(doSomething());
}finally {
reentrantLock.unlock();
}
}
public void comsumer() throws InterruptedException {
reentrantLock.lock();
try{
// 判断数据是否为空
if (queue.size() == 0){
// 消费者线程进入等待状态的信号
empty.await();
return;
}
queue.remove();
// 判断数据是否非空
if (queue.size() == max - 1){
// 生产者进入唤醒工作的信号
full.signalAll();
}
System.out.println(queue.size());
}finally {
reentrantLock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
var pc = new ProducerCustomerTest(10);
for (int i = 0; i<100; i++){
new Thread(() -> {
while (true){
try {
pc.producer();
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}).start();
}
var consumer = new Thread(() -> {
while (true){
try {
pc.comsumer();
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
});
consumer.start();
Thread.sleep(1000);
// 中断消费者
consumer.interrupt();
}
}