600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 阻塞主线程 等待异步子线程执行完毕再退出主线程 有几种写法?

阻塞主线程 等待异步子线程执行完毕再退出主线程 有几种写法?

时间:2021-10-12 12:56:38

相关推荐

阻塞主线程 等待异步子线程执行完毕再退出主线程 有几种写法?

这里实际是考察线程间的通信,正常情况下,主线程里启动异步线程执行某个方法,理论上主线程和这个异步线程是并行执行,互不干扰,但是现在要求异步线程执行完毕方法之后,才能继续执行主线程,实际是如何阻塞主线程,到底有几种写法呢?废话少说,直接上代码!

首先先给出需要执行的方法(可以自定义):

public class Compute {public static int fibo(int a) {if ( a < 2) {return 1;}return fibo(a-1) + fibo(a-2);}}

方式一:Thread.sleep()方法,让主线程休眠

代码:

public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();//异步执行new Thread(() -> {int result = Compute.fibo(7);System.out.println("异步线程执行结果:"+result);}).start();Thread.sleep(10000);System.out.println("main线程结束。。。");}

执行结果:

方式二:用join方法阻塞主线程

代码:

public static void main(String[] args) throws InterruptedException {MyThread myThread = new MyThread();myThread.start();myThread.join();System.out.println("main线程结束。。。");}private static class MyThread extends Thread{@Overridepublic void run(){int result = Compute.fibo(7);System.out.println("异步线程执行结果:"+result);}}

执行结果:

方式三:wait+synchronized阻塞主线程

代码:

public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();Object obj = new Object();MyThread myThread = new MyThread();myThread.start();synchronized (obj){obj.wait(1000);}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static class MyThread extends Thread{@Overridepublic void run(){int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}}

执行结果:

方式四:wait+notify+synchronized

public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();Object obj = new Object();MyThread myThread = new MyThread(obj);myThread.start();synchronized (obj){obj.wait();}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static class MyThread extends Thread{Object obj;public MyThread(Object obj){this.obj = obj;}@Overridepublic void run(){int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);synchronized (obj) {obj.notify();}}}

执行结果:

方式五:ReentrantLock+Condition

private final static ReentrantLock reentrantLock = new ReentrantLock(true);private final static Condition condition = reentrantLock.newCondition();public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();Object obj = new Object();//异步执行new Thread(() -> {ThreadWork05.handler(obj);}).start();ThreadWork05.mainHandler(start);}private static void mainHandler(long start) throws InterruptedException {try {reentrantLock.lock();condition.await();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}finally {reentrantLock.unlock();}}private static void handler(Object obj) {try {reentrantLock.lock();int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);condition.signal();}finally {reentrantLock.unlock();}}

执行结果:

方式六:CountDownLatch

public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(1);long start = System.currentTimeMillis();//异步执行new Thread(() -> {handler();latch.countDown();}).start();latch.await();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

方式七:LockSupport.park和unpark

public static void main(String[] args) {long start = System.currentTimeMillis();Thread mainThread = Thread.currentThread();//异步执行Thread t = new Thread(new Runnable() {@Overridepublic void run() {handler(mainThread);}});t.start();LockSupport.park(mainThread);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler(Thread mainThread) {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);LockSupport.unpark(mainThread);}

执行结果:

方式八:LockSupport.parkNanos 超时时间

public static void main(String[] args) {long start = System.currentTimeMillis();Thread mainThread = Thread.currentThread();//异步执行Thread t = new Thread(new Runnable() {@Overridepublic void run() {handler();}});t.start();LockSupport.parkNanos(mainThread, 100L);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

方式九:LockSupport.parkUntil 截止到某时间点释放方式

public static void main(String[] args) {long start = System.currentTimeMillis();Thread mainThread = Thread.currentThread();//异步执行Thread t = new Thread(new Runnable() {@Overridepublic void run() {handler();}});t.start();LockSupport.parkUntil(mainThread, System.currentTimeMillis()+1000);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

方式十:CountDownLatch.await(long t, TimeUtil t)

public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(1);long start = System.currentTimeMillis();//异步执行new Thread(() -> {handler();}).start();latch.await(100, TimeUnit.MILLISECONDS);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

方式十一:ExecutorService.submit+Future.get()阻塞 线程池

public static void main(String[] args) {long start = System.currentTimeMillis();ExecutorService executorService = new ThreadPoolExecutor(2,2,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());Future<Integer> future = executorService.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return handler();}});try {System.out.println("异步线程输出结果:"+future.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}executorService.shutdown();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

方式十二:线程池+synchronized 方式,下面要么同时锁住oo,要么同时锁住mainThread,效果一样

public static void main(String[] args) {Object oo = new Object();Thread mainThread = Thread.currentThread();long start = System.currentTimeMillis();ExecutorService executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());executorService.execute(new Runnable() {@Overridepublic void run() {handler(oo, mainThread);}});executorService.shutdown();synchronized (mainThread){try {mainThread.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler(Object oo, Thread mainThread) {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);synchronized (mainThread){mainThread.notify();}return result;}

执行结果:

方式十三:FutureTask+异步线程启动+future.get()阻塞

public static void main(String[] args) {long start = System.currentTimeMillis();FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return handler();}});//异步启动new Thread(futureTask).start();try {System.out.println("异步线程输出结果:"+futureTask.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

方式十四:CompletableFuture.supplyAsync() ,分为指定线程池和默认线程池两种

public static void main(String[] args) throws ExecutionException, InterruptedException {long start = System.currentTimeMillis();//如果不指定线程池默认使用monPool()// CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {// return handler();// });//也可以指定线程池ExecutorService executorService = new ThreadPoolExecutor(2,2,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {return handler();}, executorService);System.out.println("异步输出结果:"+integerCompletableFuture.get());//如果指定了线程池得关闭executorService.shutdown();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

方式十五:CompletableFuture.runAsync() ,分为指定线程池和默认线程池两种

public static void main(String[] args) throws ExecutionException, InterruptedException {long start = System.currentTimeMillis();//如果不指定线程池默认使用monPool()CompletableFuture<Void> integerCompletableFuture = CompletableFuture.runAsync(() -> {handler();});//也可以指定线程池// ExecutorService executorService = new ThreadPoolExecutor(2,2,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());// CompletableFuture<Void> integerCompletableFuture = CompletableFuture.runAsync(() -> {// handler();// }, executorService);//runAsync没有返回值,输出为nullSystem.out.println("异步输出结果:"+integerCompletableFuture.get());//如果指定了线程池得关闭// executorService.shutdown();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

以上是十五种阻塞主线程的方式,还有其他方式吗?欢迎留言!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。