使用join()
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子正在执行");
},"子线程");
thread.start();
thread.join();
System.out.println("主线程执行" );
}
使用CountdownLatch
CountDownLatch c = new CountDownLatch(1);
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子正在执行");
c.countDown();
},"子线程");
thread.start();
c.await();
System.out.println("主线程执行" );
}
使用线程池的while (submit.isDone())
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子正在执行");
},"子线程");
Future<?> submit = executorService.submit(thread);
submit.get();
while (submit.isDone()){
System.out.println("子线程结束");
break;
}
System.out.println("主线程执行" );
executorService.shutdown();
}
使用while(true){if(!thread.isAlive())}
public static void main(String[] args) throws InterruptedException, ExecutionException {
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子正在执行");
},"子线程");
thread.start();
while (true){
if(!thread.isAlive()) {
System.out.println("子线程结束");
break;
}
}
System.out.println("主线程执行" );
}
LockSupport
public static void main(String[] args) throws InterruptedException, ExecutionException {
//main线程
Thread thread1 = Thread.currentThread();
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子正在执行");
//解主线程
LockSupport.unpark(thread1);
}, "子线程");
thread.start();
//阻塞主线程
LockSupport.park();
System.out.println("子线程执行结束");
System.out.println("主线程执行");
}
使用CyclicBarrier
等待所有或一组线程达到一个状态,然后全部放行。
public static void main(String[] args) throws InterruptedException, Exception {
CyclicBarrier c = new CyclicBarrier(2);
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子正在执行");
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, "子线程");
thread.start();
c.await();
System.out.println("子线程执行结束");
System.out.println("主线程执行");
}
使用BlockQueue
public static void main(String[] args) throws InterruptedException, Exception {
BlockingQueue blockingQueue = new ArrayBlockingQueue(10);
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
blockingQueue.add("");
System.out.println("子正在执行");
}, "子线程");
thread.start();
blockingQueue.take();
System.out.println("子线程执行结束");
System.out.println("主线程执行");
}
使用ThreadPoolTaskExecutor
这种情况适用于先初始化线程池,然后执行任务。当存货线程数小于0时然后结束。最后主线程执行。
main函数不容易模拟出子线程执行完毕后主线程再执行的情况。
public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(1);
threadPoolTaskExecutor.setMaxPoolSize(2);
threadPoolTaskExecutor.setKeepAliveSeconds(3000);
threadPoolTaskExecutor.setQueueCapacity(1000);
threadPoolTaskExecutor.setThreadNamePrefix("CURRENCY-THREAD-POOL-" );
threadPoolTaskExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
log.error("触发拒绝策略 , 当前 活跃线程数 {} , 队列长度 {} ", executor.getActiveCount(), executor.getQueue().size());
}
});
threadPoolTaskExecutor.initialize();
Thread thread = new Thread(() -> {
for(int x = 0; x< 10000; x++){}
System.out.println("子正在执行");
},"子线程");
// 此处使用了没有返回值的方法
threadPoolTaskExecutor.execute(thread);
while (true) {
if (threadPoolTaskExecutor.getActiveCount() <= 0) {
System.out.println(">>>>>>>>>>>>>>>>>>>>任务执行完毕<<<<<<<<<<<<<<<<<<<");
break;
}
}
System.out.println("主线程执行" );
threadPoolTaskExecutor.shutdown();
}
总结:只要保证主线阻塞,子线程唤醒。就可以达到子线程执行完毕,主线程再执行的效果