package com.example.demo.test;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyContainer<T> {
final private LinkedList<T> list = new LinkedList<>();
final private int MAX = 10;//最多10个元素
private int count = 0;
private Lock lock = new ReentrantLock();
private Condition producer = lock.newCondition();//生产者条件
private Condition consumer = lock.newCondition();//消费者条件
public void put(T t){
try {
lock.lock();
while (list.size() == MAX){
producer.await();//在这个条件下,生产者线程全部等待
}
list.add(t);
++count;
consumer.signalAll();//通知消费者线程可以进行消费
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public T get(){
T t = null;
try {
lock.lock();
while (list.size() == 0){
consumer.await();//在这个条件下,消费者线程全部等待
}
t = list.removeFirst();
--count;
producer.signalAll();//通知生产者可以进行生产
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
return t;
}
public static void main(String[] args) {
MyContainer<String> container = new MyContainer<>();
//启动消费者线程
for (int i = 0;i < 10;i++){
new Thread(()->{
for(int j = 0;j < 5; j++){
System.out.println(container.get());
}
},"consumer"+i).start();
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
//启动生产者线程
for (int i = 0;i < 2;i++){
new Thread(()->{
for (int j = 0;j < 25;j++){
container.put(Thread.currentThread().getName()+"->"+j);
}
},"producer"+i).start();
}
}
}
其实java中已经有提供的阻塞式容器:如LinkedBlockingQueue(无界队列),提供了put和take方法用来添加和获取,如果容器满了或空了时调用方法就会进入等待。
ArrayBlockingQueue<>(10) (有界队列:队列中装的元素是有限的)
添加的方法区别:
1、add():如果满了,会抛异常
2、put():如果满了,进入阻塞
3、offer():有boolean返回值,添加成功true,失败false