使用 Objcet 的 wait() 和 notifyAll() 实现
使用 Lock 的 Condition 的 await/signal 实现
使用 Objcet 的 wait() 和 notifyAll() 实现
public class ThreadTest04 {
public static void main(String[] args) {
//创建一个仓库对象,共享的。
List list=new ArrayList<>();
//创建两个线程对象
//生产者线程
Thread t1=new Thread(new Producer(list));
//消费者对象
Thread t2=new Thread(new Consumer(list));
t1.setName("生产者线程");
t2.setName("消费者线程");
t1.start();
t2.start();
}
}
//生产线程
class Producer implements Runnable{
//仓库
private List list;
public Producer(List list){
this.list=list;
}
@Override
public void run() {
//一直生产(使用死循环一直模拟生产)
while (true){
//表示给仓库对象list加锁
synchronized (list){
if(list.size()>0){//大于0,说明仓库中已经有一个元素了。
//生产一个消费一个,当前线程进入等待,并释放list集合的锁
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//程序执行到这里说明仓库是空的,可以生产
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName()+"---->"+obj);
//唤醒消费者,进行消费
list.notify();
}
}
}
}
//消费线程
class Consumer implements Runnable{
//仓库
private List list;
public Consumer(List list){
this.list=list;
}
@Override
public void run() {
//一直消费
while (true){
synchronized (list){
if(list.size()==0){
//仓库已经空了
//消费者进入等待
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//程序能够执行到这里说明仓库有数据,进行消费
Object obj = list.remove(0);
System.out.println(Thread.currentThread().getName()+"---->"+obj);
//唤醒生产者生产
list.notify();
}
}
}
}
使用 BlockingQueue 实现
public class BlockingQueueTests {
public static void main(String[] args) {
BlockingQueue queue = new ArrayBlockingQueue(10);
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
class Producer implements Runnable {
private BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(20);
queue.put(i);
System.out.println(Thread.currentThread().getName() + "生产:" + queue.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
Thread.sleep(new Random().nextInt(1000));
queue.take();
System.out.println(Thread.currentThread().getName() + "消费:" + queue.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用 Lock 的 Condition 的 await/signal 实现
static int MAX_SIZE = 10;
static List<Integer> list = new ArrayList<>();
static ReentrantLock lock = new ReentrantLock();
static Condition produce = lock.newCondition();
static Condition consume = lock.newCondition();
public static void main(String[] args) {
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
}
//生产者
static class Producer implements Runnable{
@Override
public void run() {
while(true){
//第一步:获得锁
lock.lock();
try {
//第二步:判断能不能生产
if(list.size() >= MAX_SIZE){
try {
//进入此,代表库存已满,进入等待池,放弃锁,暂停线程
ableToProducer.await();
System.out.println("生产者被唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//能生产:生产一个
list.add(1);
System.out.println("生产了一个产品,现在有" + list.size() + "个产品");
//第三步:给消费者线程一个信号
ableToConsumer.signalAll();
}finally {
lock.unlock();
}
}
}
}
//消费者
static class Consumer implements Runnable{
@Override
public void run() {
while(true){
//第一步:获得锁
lock.lock();
try{
//第二步:判断能不能消费,即仓库是否为空
if(list.size() == 0){
//如果发现没有商品:就进入等待池,释放锁,线程暂停
try {
ableToConsumer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//能消费:消费一个
list.remove(0);
System.out.println("消费了一个产品,现在还有" + list.size() + "个产品");
//给生产者一个信号
ableToProducer.signalAll();
}finally {
lock.unlock();
}
}
}
}