wait方法:当前线程转入阻塞状态,让出cpu的控制权,解除锁定。
notify方法:唤醒因为wait()进入阻塞状态的其中一个线程。
notifyAll方法: 唤醒因为wait()进入阻塞状态的所有线程。
synchronized(线程同步)可以修饰方法,或者方法内部的代码块。被synchronized修饰的代码块表示:一个线程在操作该资源时,不允许其他线程操作该资源。
这三个方法都必须用synchronized块来包装,而且必须是同一把锁,不然会抛出java.lang.IllegalMonitorStateException异常。
下面是一个生产者、消费者例子:
public class ProductConsumer { public static int i = 0; public static void main(String[] args) { ProductStack ps = new ProductStack(); Product product = new Product(ps); new Thread(product).start(); Consumer consumer = new Consumer(ps); new Thread(consumer).start(); } } class Product implements Runnable { ProductStack ps = null; Product(ProductStack ps) { this.ps = ps; } @Override public void run() { while (true) { if (ProductConsumer.i < 100) { ps.push(); }else{ break; } } } } class Consumer implements Runnable { ProductStack ps = null; Consumer(ProductStack ps) { this.ps = ps; } @Override public void run() { while (true) { if (ProductConsumer.i < 100) { ps.pop(); }else{ break; } } } } class ProductStack { boolean isPro = true; public synchronized void push() { if (!isPro) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } notifyAll(); ProductConsumer.i++; System.out.print("第" + ProductConsumer.i + "个产品,生产者:" + Thread.currentThread().getName()); isPro = false; try { Thread.sleep((int) Math.random() * 200); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void pop() { if (isPro) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } notifyAll(); System.out.println(",消费者:" + Thread.currentThread().getName()); isPro = true; try { Thread.sleep((int) Math.random() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } }