目标:synchronize基本功能练习
功能:
- 上锁、解锁
- 中断
- 休眠与唤醒
ReentrantLock同样的实现:
- 相较于synchronize,ReentrantLock相对灵活更多,特别对于condition与中断以及非阻塞层面。
https://blog.csdn.net/k295330167/article/details/115675185
代码:
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/13 19:46
*/
public class SynProducerCustomer {
/**
* 最大滞留数据
*/
private final int max;
/**
* 数据队列
*/
private LinkedList<Integer> queue;
/**
* 随机数工具
*/
private static final Random RANDOM = new Random();
public SynProducerCustomer(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 {
synchronized (queue) {
if (Thread.currentThread().isInterrupted()){
throw new InterruptedException();
}
// 判断队列是否为空
if (queue.size() == max) {
// 休眠当前线程
queue.wait();
return;
}
// 判断队列是否已经有数据可处理
if (queue.size() == 1) {
// 唤醒所有线程
queue.notifyAll();
}
queue.add(doSomething());
}
}
public void comsumer() throws InterruptedException {
synchronized (queue) {
if (Thread.currentThread().isInterrupted()){
throw new InterruptedException();
}
// 判断数据是否为空
if (queue.size() == 0) {
// 休眠当前线程
queue.wait();
return;
}
queue.remove();
// 判断数据是否非空
if (queue.size() == max - 1) {
// 唤醒所有线程
queue.notifyAll();
}
System.out.println(queue.size());
}
}
public static void main(String[] args) throws InterruptedException {
var pc = new SynProducerCustomer(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();
}
}