这里用到了Lock锁机制,newCondition能为多个线程提供不同的condition,详情见代码,特定的condition能唤醒特定的线程。相比synchronized同步方法的notifyAll,多了多个等待队列,notifyAll所有的线程都会唤醒,notify只能唤醒一个线程,有可能生产者线程唤醒的是生产者线程。对于condition来说,我们将其分成生产者线程和消费者线程,在生产者线程中唤醒消费者线程。
后面再写代码的过程中遇到了一个问题,解决方法看下面
这是第一版的代码:
public class Main {
public static void main(String[] args) {
Buffer buffer = new Buffer(5);
Produce produce = new Produce(buffer);
Consumer consumer = new Consumer(buffer);
for (int i = 0; i < 5; i++) {
new Thread(produce).start();
}
for (int i = 0; i < 1; i++) {
new Thread(consumer).start();
}
}
}
class Buffer {
private ArrayList<String> string;
private int size;
private Lock lock = new ReentrantLock();
private Condition produceTh = lock.newCondition();
private Condition consumerTh = lock.newCondition();
public Buffer(int size) {
this.size = size;
string = new ArrayList<>();
}
public void put() throws InterruptedException {
//产品生产入队列
try {
lock.lock();
if (string.size() == size){
System.out.println(Thread.currentThread().getName() + " await");
produceTh.await();
}
Thread.sleep(300);
string.add("产品");
System.out.println(Thread.currentThread().getName() +" put:"+ string.size());
consumerTh.signal();
} finally {
lock.unlock();
}
}
public void take() throws InterruptedException {
//拿走产品
try {
lock.lock();
if (string.size() <= 0){
consumerTh.await();
}
Thread.sleep(300);
string.remove(string.size() -1);
System.out.println(Thread.currentThread().getName() + " take:" + string.size());
produceTh.signal();
} finally {
lock.unlock();
}
}
}
class Produce implements Runnable{
Buffer buffer;
public Produce(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true){
try {