1.wait,notify,notifyAll是Object的方法。他们必须在同步块中使用,并且当前线程必须已经获取了锁。wait方法,用来释放同步块对象上的锁,并且等待其他的线程唤醒(notify)。notify用来唤醒某一个线程,但是不会立即释放锁,被唤醒线程可以再次获取锁。notifyAll唤醒所有等待在object上面的线程,使得他们都可以再次获取锁。
一个 wait的线程,被被唤醒之后不会立刻运行,首先他得 再次获取 对象的锁,同样,一个wait的线程被中断时,他也不会立即运行,需要等待再次获取 对象的锁。
如果wait的线程可以重新运行,那么会从 他 wait的代码部分开始 继续运行。
用一个例子,来查看wait,notify的使用
public class Test { public static void main(String[] args) { new Test().test(); } private Thread t1 = new Thread(this::waitTest); private Thread t2 = new Thread(this::notifyTest); private Object o = new Object(); public void test(){ t1.start(); t2.start(); } public void waitTest() { synchronized (o) { System.out.println("before wait"); try { o.wait(); } catch (InterruptedException e) { //do nothing } System.out.println("wake up"); } } public void notifyTest(){ //休眠一段时间 让wait线程先获取锁 sleep(); synchronized (o){ System.out.println(); o.notify(); o.notify(); System.out.println("notify over"); sleep(); sleep(); System.out.println("notify sleep over"); } } public void sleep(){ try { System.out.println("sleep 3000 ms"); Thread.sleep(3000); System.out.println("sleep over"); } catch (InterruptedException e) { //do nothing } } }
2.sleep,yield是Thread的静态方法。sleep用来让当前线程休眠一段时间,在这段时间内,他不会获得CPU时间,yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程,但是也有可能该线程会继续进行。sleep和yield不必须在同步块中运行,也就是说他们其实没有太大的联系。如果在同步块中使用,他们都不会释放锁。sleep,yield总是作用于当前线程,因此用这种方式来使用sleep和yield是错误的。
Thread t = new Thread; t.sleep(); t.yield(); //他们并不能让线程t进行休眠或退让,而是作用与当前线程