JAVA多线程之Object的(wait()、notify())

来源:互联网 发布:中国网民数据 编辑:程序博客网 时间:2024/06/15 17:58
如果需要调用一个对象的wait()方法,当前线程必须持有这个对象的锁,因此调用wait()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)。

  调用某个对象的wait()方法,相当于让当前线程交出此对象的锁,然后进入等待状态,等待后续再次获得此对象的锁(Thread类中的sleep方法使当前线程暂停执行一段时间,从而让其他线程有机会继续执行,但它并不释放对象锁);

  notify()方法能够唤醒一个正在等待该对象的monitor的线程,当有多个线程都在等待该对象的monitor的话,则只能唤醒其中一个线程,具体唤醒哪个线程则不得而知。具体参照下面生产者与消费者的实例:

  缓存池:

package nc.com.thread.Condition.example;import java.util.ArrayList;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * * @ClassName: CacheCondition * @Description: 生产者与消费者共同持有的蛋糕存取池* @author A18ccms a18ccms_gmail_com * @date 2016-3-20 下午03:29:40 * */public class CacheCondition {    private int limit=100;private Lock lock = new ReentrantLock();private Condition isEmpty=lock.newCondition();private Condition isFull= lock.newCondition();private List<Cake> cache=new ArrayList<Cake>(limit);private CacheCondition(){}private static class SingleHoder{private static CacheCondition instance = new CacheCondition();}  public static CacheCondition getInstance(){  return SingleHoder.instance;  }  public void put(Cake cake){  try {  lock.lockInterruptibly();  while(cache.size()>=limit){  System.out.println(""+Thread.currentThread().getName()+"等待放入蛋糕,缓存池已满");  isFull.await();      System.out.println(""+Thread.currentThread().getName()+"被唤醒,可以继续生产");  }  cache.add(cake);  isEmpty.signal();  System.out.println(""+Thread.currentThread().getName()+"放入蛋糕:"+cake.toString()+",池中总共蛋糕"+cache.size());} catch (Exception e) {e.printStackTrace();}finally{lock.unlock();}  }    public Cake getCake(){Cake cake=null;try { lock.lockInterruptibly(); while(cache.size()<=0){ System.out.println(""+Thread.currentThread().getName()+"等待获取蛋糕,缓存池已空"); isEmpty.await();  System.out.println(""+Thread.currentThread().getName()+"被唤醒,缓存池已有蛋糕"); } cake=cache.remove(0); isFull.signal(); System.out.println(""+Thread.currentThread().getName()+"获得蛋糕:"+cake.toString()+",池中剩下总共蛋糕"+cache.size());} catch (Exception e) {        e.printStackTrace();}finally{lock.unlock();}return cake;}}
蛋糕类:

 

package nc.com.thread.Condition.example;/** * * @ClassName: Cake * @Description: 蛋糕类 * @author A18ccms a18ccms_gmail_com * @date 2016-3-20 下午03:31:02 * */public class Cake {private String color;private int price;public String getColor() {return color;}public void setColor(String color) {this.color = color;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}@Overridepublic String toString() {return "Cake [color=" + color + ", price=" + price + "]";}}

生产者:

package nc.com.thread.Condition.example;/** * * @ClassName: Productor * @Description: 蛋糕生产者* @author A18ccms a18ccms_gmail_com * @date 2016-3-20 下午03:32:05 * */public class Productor  implements Runnable{@Overridepublic void run() {try {while(true){Cake  cake =  new Cake();cake.setPrice((int) Thread.currentThread().getId());cake.setColor(""+Thread.currentThread().getName()+"放入red");CacheCondition.getInstance().put(cake);}} catch (Exception e) {e.printStackTrace();}}}

消费者:

 

package nc.com.thread.Condition.example;/** * * @ClassName: Customer * @Description: 消费者 * @author A18ccms a18ccms_gmail_com * @date 2016-3-20 下午03:32:54 * */public class Customer  implements Runnable{@Overridepublic void run() {try {while(true){Thread.sleep(2000);Cake  cake=CacheCondition.getInstance().getCake();}} catch (Exception e) {e.printStackTrace();}}}

测试类:

  

package nc.com.thread.Condition.example;public class ThreeConditionCommunication {public static void main(String[] args) { for(int num =0;num<10;num++){ Customer c = new Customer(); new Thread(c,"消费者"+num).start();  } try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();} for(int num =0;num<2;num++){ Productor p = new Productor(); new Thread(p,"生产者"+num).start(); }}}





 

0 0
原创粉丝点击