Java线程池在java开发中起到了非常重要的作用,并且我们还要将java线程池设置好,不能过大也不能小,否则都会影响程序运行,那Java线程池满了会等待吗?接下来我们就来给大家讲解一下这方面的内容。
真正的生产环境可以根据自己业务需要,选择通过实现RejectedExecutionHandler接口来自定义拒绝策略。比如把线程池无法执行的任务信息持久化写入数据库去,后台专门启动一个线程,后续等待线程池的工作负载降低了,这个后台线程就可以慢慢的从磁盘里读取之前持久化的任务重新提交到线程池。
Java线程池等待有几种方式?
1.使用线程池awaitTermination轮询
private static void executorsWait() { ExecutorService executorService = Executors.newFixedThreadPool(10); Futurefuture = executorService.submit(() -> { threadMethod(5, "-----1"); return "第一线程"; }); Futurefuture2 = executorService.submit(() -> { threadMethod(2, "++++++2"); return "第一线程"; }); executorService.shutdown(); try { while (!executorService.awaitTermination(1, TimeUnit.SECONDS)) { System.out.println("等待中"); } } catch (Exception e) { } }
2.使用获取结果Future.get()
ExecutorService executorService = Executors.newFixedThreadPool(10); List<future> listTemp = new ArrayList<>(); Futurefuture = executorService.submit(() -> { threadMethod(5, "-----1"); return "第一线程"; }); listTemp.add(future); Futurefuture2 = executorService.submit(() -> { threadMethod(2, "++++++2"); return "第一线程"; }); listTemp.add(future2); for (Futureitem : listTemp) { try { System.out.println(item.get()); } catch (Exception e) { } } executorService.shutdown();
3.使用CountDownLatch类中的等待方法
在子线程执行完成之后countDownLatch.countDown();相当于计数器减一
private static void executorsWait3() { ExecutorService executorService = Executors.newFixedThreadPool(10); CountDownLatch countDownLatch = new CountDownLatch(2); Futurefuture = executorService.submit(() -> { threadMethod(5, "-----1"); countDownLatch.countDown(); return "第一线程"; }); Futurefuture2 = executorService.submit(() -> { threadMethod(2, "++++++2"); countDownLatch.countDown(); return "第一线程"; }); executorService.shutdown(); try { countDownLatch.await(); } catch (InterruptedException e) { } }
4.使用invokeAll
通过invoke这个单词的意思就可以看出是同步的意思。它还有类似的方式invokeAny,其中的一个子线程结束就不等待了
private static void executorsWait4() { ExecutorService executorService = Executors.newFixedThreadPool(10); Callablecallable = () -> { threadMethod(5, "-----1"); return "第一线程"; }; Callablecallable2 = () -> { threadMethod(2, "++++++2"); return "第一线程"; }; List<callable> list = Arrays.asList(callable, callable2); try { List<future> futureList = executorService.invokeAll(list); executorService.shutdown(); System.out.println("获取结果---"); for (Futureitem : futureList) { System.out.println(item.get()); } } catch (Exception e) { } }
5.使用ExecutorCompletionService
ExecutorCompletionService内部管理者一个已完成任务的阻塞队列
ExecutorCompletionService引用了一个Executor, 用来执行任务
submit()方法最终会委托给内部的executor去执行任务
take/poll方法的工作都委托给内部的已完成任务阻塞队列
如果阻塞队列中有已完成的任务, take方法就返回任务的结果, 否则阻塞等待任务完成
private static void executorsWait5() { ExecutorService executorService = Executors.newFixedThreadPool(10); ExecutorCompletionService executorCompletionService = new ExecutorCompletionService(executorService); executorCompletionService.submit(() -> { threadMethod(5, "-----1"); return "第一线程"; }); executorCompletionService.submit(() -> { threadMethod(2, "-----2"); return "第二线程"; }); executorService.shutdown(); try { System.out.println(executorCompletionService.take().get()); System.out.println(executorCompletionService.take().get()); } catch (Exception e) { } } private static void threadMethod(int num, String name) { for (int i = 0; i < num; i++) { mySleep(1000); System.out.println(String.format("%s", name)); } } private static void mySleep(int millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { } }
Java线程池等待就是利用以上这几种方法,不过在设置线程池的时候,一定要合理设置,不然线程池满了肯定会影响运行!最后大家如果想要了解更多java入门知识,敬请关注奇Q工具网。
推荐阅读: