被面试是一种狠高效的学习方式。java
前几天被人面试问到了,我当时直接说用CountDownLatch(后面就呵呵了...)后来阅读了点资料,仔细想了想总结以下。面试
下面是一个报错的例子。其实彻底能够用这种古老的wait notify方式实现。可能用法不太对,欢迎指正。ide
public class ThreadANTest { public static void main(String[] args) throws InterruptedException { InnerClass ic = new InnerClass(); ic.start(); //注释掉这个会报错。。。。 //synchronized (ic) { ic.wait(); System.out.println("main...."); //} } public static class InnerClass extends Thread{ @Override public void run() { //注释掉这个会报错。。。。 //synchronized (this) { System.out.println("ThreadANTest.InnerClass.run()"); System.out.println("sleep 1s"); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("awake ... finish"); this.notify(); //} } } }
报错信息以下,大体意思是没有加监视器工具
Exception in thread "main" ThreadANTest.InnerClass.run() sleep 1s java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at com.thread.ThreadANTest.main(ThreadANTest.java:10) awake ... finishException in thread "Thread-0" java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) at com.thread.ThreadANTest$InnerClass.run(ThreadANTest.java:31)
解决办法就是,把注释放开加上监视器就行了。学习
也能够用Thread.join()实现。书上说,这个方法会等待线程完成后再执行,里面是个循环等待。“直到线程join停止后,线程的this.notifyAll会调用....” 代码以下,不用加监视器也不会报错this
public class ThreadJoinTest { public static void main(String[] args) throws InterruptedException { InnerClass inner = new InnerClass(); inner.start(); inner.join(); System.out.println("ThreadJoinTest.main().....wait inner class down"); } public static class InnerClass extends Thread{ @Override public void run() { System.out.println("ThreadJoinTest.InnerClass.run()"); System.out.println("sleep 1s"); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("awake ... finish"); } } }
输出结果以下:线程
ThreadJoinTest.InnerClass.run() sleep 1s awake ... finish ThreadJoinTest.main().....wait inner class down
这个属于JUC的工具类,从1.5开始。主要用到方法是countDown() 和 await()。 await()方法阻塞当前线程,直到计数器等于0; countDown()方法将计数器减一;code
代码以下:it
import java.util.concurrent.CountDownLatch; public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { CountDownLatch cdl = new CountDownLatch(2); InnerClass ic = new InnerClass(cdl); ic.start(); cdl.await(); System.out.println("CountDownLatchTest.main()"); } public static class InnerClass extends Thread{ private CountDownLatch cdl; public InnerClass(CountDownLatch cdl){ this.cdl = cdl; } @Override public void run() { System.out.println(1); cdl.countDown(); System.out.println(2); cdl.countDown(); } } }