在java多线程编程中,最被常常用到的即是wait与notfiy方法,这两个方法能够用来更加精确地控制被同步的代码,从而使得被同步的代码最小化,提升并发效率。 php
当某个类的某个方法被标记为synchronized时,这个方法在同一时间只能被一个线程访问。此时这个方法中的全部代码都是被同步的,只有当一个线程执行完全部的代码以后,下一个线程才能开始执行。当被同步的方法代码量比较小,并且每一步执行都很是快的时候仅仅使用synchronized关键字就够了。可是,若是被同步的方法里面有一些代码是能够被共享的,并且这些可以被共享的代码里面存在比较耗时的操做时,仅仅使用synchronized关键字就没法达到最高的效率,这个时候可使用wait与notify方法来对并发访问作更进一步的控制。首先看两段代码: html
public class TestThread { private boolean isIdle = true; public synchronized void work(){ /* * Some work which can be shared */ try { /* * to check if we can have this object's monitor */ if(!isIdle){ System.out.println(Thread.currentThread().toString() + ":I'm waiting...."); } while(!isIdle){ wait(); } /* * to set isIdle to false, I'm working.... */ this.isIdle = false; System.out.println(Thread.currentThread().toString() + ":I'm working...."); Thread.currentThread().sleep(1000); System.out.println(Thread.currentThread().toString() + ":I'm finished...."); /* * to notify all other thread which is waiting for this object's monitor */ this.isIdle = true; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } }
在上面的类中定义了一个方法work,在这个方法中的try块以前能够执行一些可共享的代码,而try块中的代码是不可以被共享的。所以,咱们在进入try以后会首先判断标志isIdle是否为true,若是为true就表示当前没有其余线程正在访问,所以当前线程就得到了执行try块中代码的权利。在执行代码前当前线程会将isIdle设置成false,这样当其余线程进入try,以后就会发现isIdle为false,从而进入等待状态。
当一个线程执行完try中的代码以后,会将isIdle从新设置为true,同是使用notifyAll方法通知全部等待得到执行try块中代码的权利的线程。
下面这个类用来测试上面的TestThread: java
public class ThreadTester { private static TestThread tt = new TestThread(); public static void main(String[] args){ for(int i = 0; i < 5; i++){ new Thread(new Runnable(){ public void run(){ tt.work(); } }).start(); } } }
这个类在main方法中启动了五个不一样线程访问TestThread的work方法,从打印结果中能够看出,每次线程的执行顺序都会有些许的差异。 编程
第一次运行:多线程
Thread[Thread-0,5,main]:I'm working.... Thread[Thread-0,5,main]:I'm finished.... Thread[Thread-1,5,main]:I'm working.... Thread[Thread-1,5,main]:I'm finished.... Thread[Thread-3,5,main]:I'm working.... Thread[Thread-3,5,main]:I'm finished.... Thread[Thread-2,5,main]:I'm working.... Thread[Thread-2,5,main]:I'm finished.... Thread[Thread-4,5,main]:I'm working.... Thread[Thread-4,5,main]:I'm finished....
第二次运行: 并发
Thread[Thread-0,5,main]:I'm working.... Thread[Thread-0,5,main]:I'm finished.... Thread[Thread-2,5,main]:I'm working.... Thread[Thread-2,5,main]:I'm finished.... Thread[Thread-1,5,main]:I'm working.... Thread[Thread-1,5,main]:I'm finished.... Thread[Thread-4,5,main]:I'm working.... Thread[Thread-4,5,main]:I'm finished.... Thread[Thread-3,5,main]:I'm working.... Thread[Thread-3,5,main]:I'm finished....
推荐阅读:高并发
Thread类的sleep()方法和对象的wait()方法均可以让线程暂停执行,它们有什么区别?测试