首页

关于java主线程等待子线程常用几种实现方式代码demo示例

标签:线程同步demo,CountDownLatch用法,Semaphore信号量用法     发布时间:2021-05-10   

一、前言

关于java场景多线程应用场景中,主任务线程任务结束完成依赖所有子任务线程都执行完成后,主任务才算完成最终任务,下面根据不同应用方式整理具体代码示例进行说明。

二、代码示例

方法1:通过线程池executors.isTerminated()进行等待子任务线程完成

package thread.wait;@b@@b@import java.util.concurrent.ExecutorService;@b@import java.util.concurrent.Executors;@b@@b@public class MainThreadWaitTest1 {@b@	@b@	private static ExecutorService executors;@b@	@b@	public static void main(String[] args)  throws  Exception{@b@		//main job开始i@b@		System.out.println(Thread.currentThread().getName()+" run begin............");@b@		@b@		executors = Executors.newScheduledThreadPool(3);@b@		for(int i=0;i<10;i++){@b@			executors.submit(new Runnable() {@b@				@Override@b@				public@b@				void run() {@b@					//子线程开始工作@b@					System.out.println(Thread.currentThread().getName()+" working......");@b@					try {@b@						Thread.sleep(50);@b@					} catch (InterruptedException e) {@b@					}@b@					//子线程完成工作@b@					System.out.println(Thread.currentThread().getName()+" work finished......");@b@				}@b@			}); @b@		}@b@		@b@		executors.shutdown();@b@		//等待@b@		while (!executors.isTerminated()) {@b@			System.out.println(Thread.currentThread().getName()+"等待子线程完成任务,waiting...");@b@			Thread.currentThread().sleep(500);@b@		}@b@		@b@		//等待所有子任务线程工作完成后,总的main线程算完成任务@b@		System.out.println(Thread.currentThread().getName()+" all jobs finished ***************");@b@	}@b@@b@}

控制台打印结果如下

main run begin............@b@pool-1-thread-2 working......@b@main等待子线程完成任务,waiting...@b@pool-1-thread-1 working......@b@pool-1-thread-3 working......@b@pool-1-thread-3 work finished......@b@pool-1-thread-1 work finished......@b@pool-1-thread-2 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-2 working......@b@pool-1-thread-3 working......@b@pool-1-thread-3 work finished......@b@pool-1-thread-2 work finished......@b@pool-1-thread-1 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-3 working......@b@pool-1-thread-1 working......@b@pool-1-thread-2 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-3 work finished......@b@pool-1-thread-2 work finished......@b@main all jobs finished ***************

方法2:Semaphore信号量方式 - 通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

package thread.wait;@b@@b@import java.util.concurrent.ExecutorService;@b@import java.util.concurrent.Executors;@b@import java.util.concurrent.Semaphore;@b@@b@public class MainThreadWaitTest2 {@b@	@b@	private  static  Semaphore semaphore=new Semaphore(3);@b@	@b@	private static ExecutorService executors;@b@	@b@	public static void main(String[] args)  throws  Exception{@b@		//main job开始i@b@		System.out.println(Thread.currentThread().getName()+" run begin............");@b@		@b@		executors = Executors.newScheduledThreadPool(3);@b@		for(int i=0;i<10;i++){@b@			executors.submit(new Runnable() {@b@				@Override@b@				public void run() {@b@					try {@b@						semaphore.acquire();@b@						//子线程开始工作@b@						System.out.println(Thread.currentThread().getName()+" working......");@b@						Thread.sleep(50);@b@					} catch (Exception e) {@b@						e.printStackTrace();@b@					}@b@					semaphore.release();@b@					//子线程完成工作@b@					System.out.println(Thread.currentThread().getName()+" work finished......");@b@				}@b@			}); @b@			Thread.sleep(50);@b@		}@b@		@b@		//等待所有子任务线程工作完成后,总的main线程算完成任务@b@		semaphore.acquireUninterruptibly();@b@//		semaphore.acquire(3);@b@		System.out.println(Thread.currentThread().getName()+" all jobs finished ***************");@b@	}@b@@b@}

控制台打印结果如下

main run begin............@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-2 work finished......@b@pool-1-thread-3 working......@b@pool-1-thread-3 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-2 work finished......@b@pool-1-thread-3 working......@b@pool-1-thread-3 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-2 work finished......@b@main all jobs finished ***************

方法3:CountDownLatch方式 - 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕。

package thread.wait;@b@@b@import java.util.concurrent.CountDownLatch;@b@import java.util.concurrent.ExecutorService;@b@import java.util.concurrent.Executors;@b@@b@public class MainThreadWaitTest3 {@b@	@b@	private static final CountDownLatch countDownLatch = new CountDownLatch(10);@b@	@b@	private static ExecutorService executors;@b@	@b@	public static void main(String[] args)  throws  Exception{@b@		//main job开始i@b@		System.out.println(Thread.currentThread().getName()+" run begin............");@b@		@b@		executors = Executors.newScheduledThreadPool(3);@b@		for(int i=0;i<10;i++){@b@			executors.submit(new Runnable() {@b@				@Override@b@				public@b@				void run() {@b@					try {@b@						//子线程开始工作@b@						System.out.println(Thread.currentThread().getName()+" working......");@b@//						Thread.sleep(50);@b@					} catch (Exception e) {@b@					} finally {@b@                        countDownLatch.countDown();  //这个不管是否异常都需要数量减,否则会被堵塞无法结束@b@                    }@b@@b@					//子线程完成工作@b@					System.out.println(Thread.currentThread().getName()+" work finished......");@b@				}@b@			}); @b@			Thread.sleep(50);@b@		}@b@		@b@		//等待所有子任务线程工作完成后,总的main线程算完成任务@b@		countDownLatch.await();@b@		System.out.println(Thread.currentThread().getName()+" all jobs finished ***************");@b@	}@b@@b@}

控制台打印结果如下

main run begin............@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-2 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-3 working......@b@pool-1-thread-3 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-2 work finished......@b@pool-1-thread-1 working......@b@pool-1-thread-1 work finished......@b@pool-1-thread-3 working......@b@pool-1-thread-3 work finished......@b@pool-1-thread-2 working......@b@pool-1-thread-2 work finished......@b@main all jobs finished ***************
  • ◆ 相关内容