Java中根类 Object中 wait()、notify()、notifyAll() 三个方法都是native修饰的方法。 每个对象都有相对应的方法,使用这三种方法的前提是,正在运行的线程必须拥有该对象的锁,即在synchronized(){}中。
wait():当前线程放弃该对象的锁,线程处于休眠状态,直到notify()或者notifyAll()之后,才有可能继续执行。
notify():唤醒某个放弃该对象锁的线程。
notifyAll():唤醒全部放弃该对象锁的线程。
注意:wait() 和sleep() 两者的共同点都是使当前线程放弃CPU控制权,线程处于挂起状态,但是wait()方法会放弃synchronized块中对象的锁,但是sleep()方法却不会释放掉synchronized块中对象的锁。sleep()方法是Thread对象中的方法, wait()方法是每个对象都有的。
下面是一个比较经典的生产者-消费者模式的多线程例子:
package thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @author:zyy * @名称: 生产者-消费者 * */ public class ProduceAndConsumer { public static void main(String[] args) { Product pro = new Product(); Thread thread1 = new Thread(new Produce(pro),"thread1"); Thread thread2 = new Thread(new Consumer(pro),"thread2"); Thread thread3 = new Thread(new Produce(pro),"thread3"); Thread thread4 = new Thread(new Consumer(pro),"thread4"); ExecutorService servicePool = Executors.newCachedThreadPool(); servicePool.execute(thread1); servicePool.execute(thread2); servicePool.execute(thread3); servicePool.execute(thread4); // // thread1.start(); // thread2.start(); // thread3.start(); // thread4.start(); // } } class Product { private int size ; //当前容量 private int MAX_SIZE = 10; //最大容量 /** * 消费 */ public synchronized void get(){ while(size<=0){ System.out.println("没有商品,为空"); try { this.wait(); //当没有东西可以消费的话,当前线程放弃Product对象的锁,直到有别的线程唤醒该对象锁 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " --"); } System.out.println("开始消费 --" + size--); //消费了之后,就唤醒之前放弃该对象锁的线程,(注意: 虽然notify()唤醒了,但是必须要等到该synchronized内的代码块执行完毕) this.notify(); } /** * 生产 */ public synchronized void add(){ while(size>=MAX_SIZE){ System.out.println("商品已经满了,不能存放"); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("开始生产 --" + size++); this.notify(); //生产了,然后之前放弃该对象锁的线程 } } class Produce implements Runnable{ private Product product; public Produce(Product product) { super(); this.product = product; } @Override public void run() { while(true){ product.add(); /* try { TimeUnit.SECONDS.sleep(1); //这里设置时间,可以更直观的观看消费的情况 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ } } } class Consumer implements Runnable{ private Product product; public Consumer(Product product) { super(); this.product = product; } @Override public void run() { while(true){ product.get(); // try { // TimeUnit.SECONDS.sleep(2); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } } } }
如有不正确,欢迎拍砖!