JAVA多线程之Object的(wait()、notify())
2016-03-20 15:29
661 查看
如果需要调用一个对象的wait()方法,当前线程必须持有这个对象的锁,因此调用wait()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)。
调用某个对象的wait()方法,相当于让当前线程交出此对象的锁,然后进入等待状态,等待后续再次获得此对象的锁(Thread类中的sleep方法使当前线程暂停执行一段时间,从而让其他线程有机会继续执行,但它并不释放对象锁);
notify()方法能够唤醒一个正在等待该对象的monitor的线程,当有多个线程都在等待该对象的monitor的话,则只能唤醒其中一个线程,具体唤醒哪个线程则不得而知。具体参照下面生产者与消费者的实例:
缓存池:
生产者:
消费者:
测试类:
调用某个对象的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; } @Override public 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{ @Override public 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{ @Override public 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(); } } }
相关文章推荐
- Objective-C中不同方式实现锁
- 缺少动态连接库.so--cannot open shared object file: No such file or directory
- Java基础之Object篇
- case class与case object实战
- Objective-C中KVO简单用法
- JAVA第七节-继承,继承中方法重写,继承的初始化顺序,final关键字,super关键字,object类
- 共享池部分-library cache、library cache object handle、library cache object、shared cursor、session cursor和解析
- Object-C基础-07-内存管理
- Object-C基础-08-protocol
- Hibernate逍遥游记-第5章映射一对多-01单向<many-to-one>、cascade="save-update"、lazy、TransientObjectException
- java基础之Classloading and class objects
- Objective-C错误处理
- Objective-C KVC&KVO
- Object.prototype.toString应用和原理探析
- Objective-C内存管理
- Objective-C block (块)
- Objective-C集合
- Objective-C之NSNumber
- Programming with Objective-C——翻译2章
- DOM和JQUERY 对HTML标记修改的冲突之 swfobject