生产者·和消费者问题
wait() 通过notify()或者notifyAll()的方法来唤醒;sleep()通过不用唤醒,到了一定时间自动苏醒
notify()
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
notifyAll()
唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争
实现生产者·消费者的问题
package cn.com.jlu.demo;
import java.util.LinkedList;
public class ConsumerProduct {
/**
* @param args
* 生产者向篮子中放苹果,最多五个,消费者取
* 消费者从篮子中取苹果,
*/
public static void main(String[] args) {
//实例化一个苹果对象。为了生产者和消费者操作篮子对象从而实现取、拿苹果的操作
Basket basket=new Basket();
Consumers con=new Consumers(basket);
con.start();
Productors p=new Productors(basket);
p.start();
}
}
//创建一个消费者对象,操作的对象就是篮子
class Consumers extends Thread
{
Basket bas=null;
public Consumers(Basket bas) {
super();
this.bas = bas;
}
//实现的功能就是取苹果,调用篮子中取取苹果的方法
@Override
public void run() {
bas.popApple();
}
}
//创建一个生产者的线程,目的是为了向篮子中放苹果
class Productors extends Thread
{
Basket bas=null;
public Productors(Basket bas) {
super();
this.bas = bas;
}
@Override
public void run() {
bas.pushApple();
}
}
//用来存或者放苹果
class Basket
{
//将苹果放到list中
LinkedList<Apple> apple=new LinkedList<Apple>();
//将10个苹果装入篮子中,分两轮,由于苹果是共享资源,所以放取苹果都同步进行
public synchronized void pushApple()
{
for(int i=0;i<10;i++)
{
Apple ap=new Apple(i);
pushMethod(ap);
}
}
//取苹果和拿苹果是互斥的,synchronized修饰方法
public synchronized void popApple()
{
for(int i=0;i<20;i++)
{
popMethod();
}
}
//将苹果放在篮子中
private void pushMethod(Apple ap)
{
//Apple apple=new Apple();
//如果篮子中的苹果达到了5个,则等待消费者取拿苹果,
if(apple.size()==5)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(500);//每隔500ms放入苹果
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
apple.addFirst(ap);//将苹果放入篮子中
System.out.println("放入"+ap.toString());
//唤醒消费者去拿苹果
notify();
}
//从篮子中取苹果
private void popMethod()
{
//如果篮子中没有苹果则等待生产者放苹果
if(apple.size()==0)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);//假设500ms取一个苹果
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 将苹果取出
Apple ap=apple.removeFirst();
System.out.println("取出"+ap.toString());
notify();
}
}
class Apple
{
private int id;//苹果标号
public Apple(int id) {
super();
this.id = id;
}
@Override
public String toString() {
return "Apple [id=" + (id+1) + "]";
}
}