今天写一个测试类,主要是测试wait(long timeout)到底会不会自动notify,到后来发现
一些很诡异的东西。
package com.hp.thread.chapter04; public class WaitAndNotify { private Object obj = new Object(); public static void testPureWait(){ new Thread(new Runnable(){ public void run() { synchronized (this) { try { System.out.println("thread 0"); wait(); System.out.println("thread 0 waited..."); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(new Runnable(){ public void run() { synchronized (this) { try { System.out.println("thread 1"); wait(1000); System.out.println("thread 1 waited..."); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } public void testWait1000(){ new Thread(new Runnable(){ public void run() { System.out.println("thread 0 " + this); synchronized (obj) { while(true){ try { System.out.println("thread 0 running..."); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); new Thread(new Runnable(){ public void run() { System.out.println("thread 1 " + this); synchronized (obj) { try { while(true){ wait(1000); System.out.println("thread 1 waited..."); } } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } //通过打印出来的this,发现2个是不同的结果,为什么呢? //因为this是指向当前对象的引用,不过方法中都是new Thread(new Runnable(){}).start() //方式来生成,都是通过匿名的方式,所以每次的this都是指向new Thread()的WaitAndNotify对象 public void testWait1000_2(){ new Thread(new Runnable(){ public void run() { synchronized (this) { while(true){ try { System.out.println("thread 0"); System.out.println("thread 0 running..."); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); new Thread(new Runnable(){ public void run() { synchronized (this) { try { while(true){ System.out.println("thread 1"); wait(1000); System.out.println("thread 1 waited..."); } } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } public static void testWait(){ new Thread(new Runnable(){ public void run() { while(true){ synchronized (this) { try { System.out.println("..."); wait(); System.out.println("waited..."); notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); new Thread(new Runnable(){ public void run() { while(true){ synchronized (this) { try { notifyAll(); System.out.println("notify..."); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); } /** * @param args */ public static void main(String[] args) { // testPureWait(); // testWait(); new WaitAndNotify().testWait1000(); } }
调用testWait1000_2方法得到的结果不是我期望(线程0始终在运行,线程1是不会运行的),但世界的结果恰恰相反,好事2个线程不相干,测试结果如下
thread 0 thread 0 running... thread 1 thread 1 waited... thread 0 thread 0 running... thread 1 thread 0 thread 0 running... thread 1 waited... thread 1
但是运行testWait1000正好是我要的结果,开始百思不得其解,后来打印this发现mystery了
thread 0 com.hp.thread.chapter04.WaitAndNotify$3@525483cd thread 0 running... thread 1 com.hp.thread.chapter04.WaitAndNotify$4@67f1fba0 thread 0 running... thread 0 running... thread 0 running... thread 0 running...
发现2个this的地址完全不一样,细想一下豁然开朗。