多线程(Java)等待唤醒机制之消费者生产者示例

多线程之等待唤醒机制

前面多线程的文章中,我们提到了线程状态,有一个状态是WAITING状态,也就是等待状态。

这个状态是指调用了Thread.wait(); 方法后线程失去CPU的执行资格,CPU就算做着随机切换,也不会切换到该线程,只有使用了notify() 方法唤醒了此线程,该线程才能重新获得CPU的执行资格。

而wait() notify() notifyAll() 其实是Object对象的方法,这也就意味着所有对象都有这个方法,而我们等待,唤醒的线程,其实是将其放入了调用此方法对象的后台池子里。

我们来利用一个代码示例来看一下等待唤醒机制。

单生产者,单消费者示例

class Resource{
	private boolean mIsProduced = false;
	private int count;
	
	
	
	public boolean isProduced() {
		return mIsProduced;
	}

	public void setProduced(boolean isProduced) {
		this.mIsProduced = isProduced;
	}

	public void produce() {
		count++;
		System.out.println("生产者线程 --->  " + Thread.currentThread().getName() + " 生产商品 " + count + "号");
	}
	
	public void consume() {
		System.out.println("消费者线程 ---> " + Thread.currentThread().getName() + "消费" + count + "商品");
	}
}
class Producer extends Thread{
	private Resource mResource;
	
	public Producer(Resource resource) {
		this.mResource = resource;
	}
	
	@Override
	public void run() {
		while(true) {
			synchronized (mResource) {
				if(mResource.isProduced()) {
					try {
						mResource.notify();
						mResource.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}else {
					mResource.produce();
					mResource.setProduced(true);
				}
			}
		}
	}
}
class Consumer extends Thread{
	private Resource mResource;
	
	public Consumer(Resource resource) {
		this.mResource = resource;
	}
	
	@Override
	public void run() {
		while(true) {
			synchronized (mResource) {
				if(!mResource.isProduced()) {
					try {
						mResource.notify();
						mResource.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}else {
					mResource.consume();
					mResource.setProduced(false);
				}
			}
		}
	}
	
}
package com.evan.producer_consumer;

public class Demo {

	public static void main(String[] args) {
		Resource resource = new Resource();
		Producer producer = new Producer(resource);
		Consumer consumer = new Consumer(resource);
		producer.start();
		consumer.start();
	}
}

 

 运行结果

多线程(Java)等待唤醒机制之消费者生产者示例_第1张图片

我们有一个资源类即 Resource.class

有一个boolean的isProduced,用于记录是否已经生产了商品。还有一个count,记录生产商品的数量。

我们还有两条线程,一条Producer生产者线程,一条Consumer消费者线程。

在Producer的run方法中,有一个死循环,在Synchronized代码块中,我们使用了Resource这个对象作为锁。

当判断到isProduce为false时,我们就直接生产一个商品,当为true时,我们就先通过resource.notify()来唤醒Consumer,然后将自己线程睡眠。

在Consumer的run方法中,当判断到isProduce为true时,我们就直接消费一个商品,当为false时,我们就通过resource.notify*来唤醒Producer,然后将自己睡眠。

这样就利用了等待唤醒机制,来达到效果图上这样的输出效果。

也就是一个线程操作完毕后睡眠自己,但睡眠之前先唤醒对方线程,而这两条线程使用的是同一个锁,而两条线程也都睡眠在同一个锁背后的池子中。

你可能感兴趣的:(Java)