public class ProducerConsumer {
private static boolean run = true;
private static final Integer MAX_CAPACITY = 20;
private static final LinkedBlockingQueue queue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
new Producer().start();
new Consumer().start();
}
static class Producer extends Thread {
@Override
public void run() {
while (run) {
synchronized (queue) {
if (queue.size() == MAX_CAPACITY) {
try {
System.out.println("队列已满,等待消费");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String s = UUID.randomUUID().toString();
System.out.println("生产者开始生产:" + s);
try {
queue.put(s);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
queue.notifyAll();
}
}
}
}
static class Consumer extends Thread {
@Override
public void run() {
while (run) {
synchronized (queue) {
if (queue.size() == 0) {
try {
System.out.println("暂无消息,等待生产");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
System.out.println("消费者开始消费:" + queue.take());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
queue.notifyAll();
}
}
}
}
}
1、wait()、notify()、notifyAll()只能在synchronized关键字修饰的代码中使用,否则会抛出异常;
2、wait()释放对象锁,进入等待状态;
3、notify()随机唤醒一个等待的线程;注意:jdk1.8是公平唤醒,第一个等待,第一个被唤醒;
4、notifyAll()唤醒所有等待的线程,所有的线程重新竞争对象锁,竞争到锁的线程进入就绪状态,获得cpu时间片开始执行,其他线程再次回到等待状态;
5、三个方法都是Object类的方法。