主线程等待子线程完成后执行的实现方式

被面试是一种狠高效的学习方式。

前几天被人面试问到了,我当时直接说用CountDownLatch(后面就呵呵了...)后来阅读了点资料,仔细想了想总结如下。

古老的wait notify

下面是一个报错的例子。其实完全可以用这种古老的wait notify方式实现。可能用法不太对,欢迎指正。

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会调用....” 代码如下,不用加监视器也不会报错

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()方法将计数器减一;

代码如下:

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();
			
		}
		
		
	}
}

转载于:https://my.oschina.net/u/1444945/blog/1815301

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值