主線程等待子線程完成後執行的實現方式

被面試是一種狠高效的學習方式。java

前幾天被人面試問到了,我當時直接說用CountDownLatch(後面就呵呵了...)後來閱讀了點資料,仔細想了想總結以下。面試

古老的wait notify

下面是一個報錯的例子。其實徹底能夠用這種古老的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()實現

也能夠用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

CountDownLatch實現

這個屬於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();
			
		}
		
		
	}
}
相關文章
相關標籤/搜索