java实现多个子线程执行完毕后,再执行主线程

java实现多个子线程执行完毕后,再执行主线程

一、业务场景
1、 在做批量数据处理时,需执行多个存储过程。 执行1个存储过程,大概需10分钟,若一个一个的执行,将会耗时很久。 经过测试发现,数据库资源够用,具备同时执行多个存储过程的能力。
2、 在java中,到执行存储过程service时,异步开启子线程执行,存储过程service。 遇到问题是:主线程和子线程都在同时执行,这时,子线程结果还未执行完毕,主线程已经完毕,结果反馈给前端了。 ( 实际数据库中的存储过程还在执行中。。)
3、需求是: 主线程需等待子线程执行完毕后,才将结果返回给前端。
4、 大概业务代码如下:
public class MultiThread {
	public static void main(String[] args) {
		System.out.println("主线程开始执行....");
		for (int i = 0; i < 3; i++) {
			new Thread(){
				@Override
				public void run() {
					try {
						System.out.println(Thread.currentThread().getName()+"  开始执行存储过程..");						
						Thread.sleep(2000);
						System.out.println(Thread.currentThread().getName()+"  存储过程执行完毕...");						
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				};
			}.start();
		}
		System.out.println("主线程执行完毕....");
	}
}

5、执行结果如下:
主线程开始执行....
主线程执行完毕....
Thread-2 开始执行存储过程..
Thread-0 开始执行存储过程..
Thread-1 开始执行存储过程..
Thread-2 存储过程执行完毕...
Thread-0 存储过程执行完毕...
Thread-1 存储过程执行完毕...

6、 很明显,该结果不符合业务需求,业务需求的是:
主线程开始执行....
Thread-0 开始执行存储过程..
...
Thread-2 存储过程执行完毕...
主线程执行完毕....

二、问题解决办法一 ( CountDownLatch) 实现
1、CountDownLatch: 是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。 ( CountDownLatch是什么
2、 代码实现如下:
public class MultiThreadToCountDownLatch {
	public static void main(String[] args) throws InterruptedException {
		//1、 创建CountDownLatch 对象, 设定需要计数的子线程数目
		final CountDownLatch latch=new CountDownLatch(3);
		System.out.println("主线程开始执行....");
		for (int i = 0; i < 3; i++) {
			new Thread(){
				@Override
				public void run() {
					try {
						System.out.println(Thread.currentThread().getName()+"  开始执行存储过程..");						
						Thread.sleep(2000);
						System.out.println(Thread.currentThread().getName()+"  存储过程执行完毕...");						
						//2、子线程执行完毕,计数减1
						latch.countDown();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				};
			}.start();
		}
		System.out.println("等待子线程执行完毕...");
		//3、 当前线程挂起等待 
		latch.await();
		System.out.println("主线程执行完毕....");
	}
}

3、 执行结果如下:
主线程开始执行....
等待子线程执行完毕...
Thread-1 开始执行存储过程..
Thread-2 开始执行存储过程..
Thread-0 开始执行存储过程..
Thread-1 存储过程执行完毕...
Thread-2 存储过程执行完毕...
Thread-0 存储过程执行完毕...
主线程执行完毕....
4、 由执行结果可知,已经达到业务需求了。


三、其他实现方法补充
1、CyclicBarrier 和 Semaphore: http://www.importnew.com/21889.html
2、 使用 join()及 CountDownLatch 和 CyclicBarrier 区别: http://blog.csdn.net/u011277123/article/details/54015755




猜你喜欢

转载自blog.csdn.net/haha_sir/article/details/79521028