java.lang.Object类提供了wait()、notify()、notifyAll()方法,这些方法只有在synchronized或synchronized代码块中才能使用,是否就会报java.lang.IllegalMonitorStateException异常。
当另外线程执行了某对象的notify方法之后,会唤醒在此对象等待池中的某个线程,使之成为可运行线程。notifyAll是唤醒在此对象等待池中所有的等待线程。
下面我们来看看一个比较经典的问题:
生产者/消费者问题
问题描述如下:
生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有固定数量的产品,如果生产者生产了过多的产品,店员会叫生产者等一下,如果店中有空位放产品了再通知;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取产品。
这里可能出现问题有以下两个:
1. 生产者比消费者快时,消费者会漏掉一些数据没有取到
2. 消费者比生产者快时,消费着会取相同的数据
/**
* 理解wait和notify方法
* 生产者(Producer)/消费者(Consumer)问题
* @author admin
*
*/
public class ProductTest
{
/**
* @param args
*/
public static void main(String[] args)
{
Clerk clerk = new Clerk();
Thread producerThread = new Thread(new Producer(clerk));
Thread consumerThread = new Thread(new Consumer(clerk));
producerThread.start();
consumerThread.start();
}
}
/**
* 店员
* @author admin
*
*/
class Clerk
{
//最大产品数
private static final int MAX_PRODUCT = 20;
//最小产品数
private static final int MIN_PRODUCT = 0;
//默认为0个产品
private int product = 0;
/**
* 生产者生产出来的产品交给店员
*/
public synchronized void addProduect()
{
if(this.product >= MAX_PRODUCT)
{
try
{
wait();
System.out.println("产品已满,请稍候再生产");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
return;
}
this.product++;
System.out.println("生产者生产第" + this.product + "个产品.");
notifyAll(); //通知等待区的消费者可以取出产品了
}
/**
* 消费者从店员取产品
*/
public synchronized void getProduct()
{
if(this.product <= MIN_PRODUCT)
{
try
{
wait();
System.out.println("缺货,稍候再取");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return;
}
System.out.println("消费者取走了第" + this.product + "个产品.");
this.product--;
notifyAll(); //通知等待去的生产者可以生产产品了
}
}
/**
* 生产品线程
* @author admin
*
*/
class Producer implements Runnable
{
private Clerk clerk ;
public Producer(Clerk clerk)
{
this.clerk = clerk;
}
public void run()
{
System.out.println("生产者开始生产产品.");
while(true)
{
try
{
Thread.sleep((int)(Math.random() * 10) * 100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
clerk.addProduect(); //生产产品
}
}
}
/**
* 消费线程
* @author admin
*
*/
class Consumer implements Runnable
{
private Clerk clerk;
public Consumer(Clerk clerk)
{
this.clerk = clerk;
}
public void run()
{
System.out.println("消费者开始取走产品.");
while(true)
{
try
{
Thread.sleep((int)(Math.random() * 10) * 100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
clerk.getProduct(); //取产品
}
}
}
总结:
对wait,notify,notifyAll方法理解可以为归纳为图所示
ps:最后一个o.notify是o.notifyAll,上传的时候没有注意到,抱歉了!
- 大小: 40.9 KB
分享到:
相关推荐
wait和notify讲解
Java 同步方式 wait和notify/notifyall
使用Java多线程的wait和notify方法实现最简单的生产者消费者模式
java代码-wait-notify 生产者消费者
举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内容待消费(不为空)。相应的,消费者可以通知生产者可以开始生成更多的数据,...
java中多线程编程notify、wait的使用
wait()、notify()和notifyAll()方法1---马克-to-win java视频
3(深入理解Wait、Notify和Wait与sleep区别).rar
开一个子线程来完成一个循环处理的工作,我在主线程中能灵活控制这个子线程的开始、暂停/继续、结束。
java多线程之wait,notify的用法([ 详解+实例 ]).
JAVAWAIT和NOTIFY的用法.pdf
java-wait和notify的用法.pdf
Java多线程的样例代码,工程,内含wait()、notify()和sychronized的使用范例。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
主要介绍了浅谈线程通信wait,notify作用,具有一定借鉴价值,需要的朋友可以参考下
主线程去控制子线程wait与notify
源码—Java多线程5—死锁和wait notify notifyAll
主要介绍了java多线程wait,notify,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面小编和大家一起来学习一下吧