wait和notify以及notifyAll的使用方法

来源:互联网 发布:高洛峰 细说php 编辑:程序博客网 时间:2024/05/30 23:02
public class WaitTest {public static void main(String[] args) {final WaitTest w = new WaitTest();for(int i=0; i<4; i++){new Thread(new Runnable(){public void run() {w.accessBlock3();}}).start();}}//访问块,使用synchronized来进行线程的锁和同步public synchronized void accessBlock1(){System.out.println(Thread.currentThread().getName()+"进入访问块*******");System.out.println(Thread.currentThread().getName()+"线程访问中...");System.out.println(Thread.currentThread().getName()+"开始操作---------");System.out.println(Thread.currentThread().getName()+"操作中-----------");System.out.println(Thread.currentThread().getName()+"结束操作---------");System.out.println();}public void accessBlock2(){System.out.println(Thread.currentThread().getName()+"进入访问块*******");synchronized(this){System.out.println(Thread.currentThread().getName()+"线程访问中...");System.out.println(Thread.currentThread().getName()+"开始操作---------");System.out.println(Thread.currentThread().getName()+"操作中-----------");System.out.println(Thread.currentThread().getName()+"结束操作---------");System.out.println();sleep();}}private boolean isAccess = true;//不使用synchronized,使用wait和notify来进行线程的锁和同步public void accessBlock3(){if(!isAccess){System.out.println(Thread.currentThread().getName()+"线程被阻塞.等待中...");}if(!isAccess){synchronized(this){//第10行try {this.wait();//如果不能访问,则线程等待} catch (InterruptedException e) {e.printStackTrace();}}}isAccess = false;//锁住,使一些线程在上面的方法中被阻塞System.out.println(Thread.currentThread().getName()+"线程访问中...");sleep();System.out.println(Thread.currentThread().getName()+"开始操作---------");System.out.println(Thread.currentThread().getName()+"操作中-----------");System.out.println(Thread.currentThread().getName()+"结束操作---------");System.out.println();isAccess = true;synchronized(this){//第20行//当前线程执行结束,随机唤醒其中一个等待线程//这里如果使用notifyAll,等待的线程会一起执行,会造成线程不同步this.notify();}/** * 在第10行和第20行要加上synchronized的目的:可参考http://longdick.iteye.com/blog/453615 * 任何时刻,对象的控制权只能被一个程序拥有 * 无论是使用wait,notify,notifyall在执行的过程中都必须保证当前运行的线程获得了对象的控制权 * 如果没有控制权的线程就会抛出java.lang.IllegalMonitorStateException异常 */}public void sleep(){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}/**  执行结果:    Thread-0线程访问中...Thread-2线程被阻塞.等待中...Thread-1线程被阻塞.等待中...Thread-3线程被阻塞.等待中...Thread-0开始操作---------Thread-0操作中-----------Thread-0结束操作---------Thread-3线程访问中...Thread-3开始操作---------Thread-3操作中-----------Thread-3结束操作---------Thread-2线程访问中...Thread-2开始操作---------Thread-2操作中-----------Thread-2结束操作---------Thread-1线程访问中...Thread-1开始操作---------Thread-1操作中-----------Thread-1结束操作--------- */}