package pool; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * @ 堆代码 duidaima.com */ public class BaiLiIsShutdownThreadPoolDemo { /** * 创建一个最大线程数15的线程池 */ public static ThreadPoolExecutor pool = new ThreadPoolExecutor( 10, 15, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); /** * 线程执行方法,随机等待0到10秒 */ private static void sleepMethod(int index){ try { long sleepTime = new Double(Math.random() * 10000).longValue(); Thread.sleep(sleepTime); System.out.println("当前线程执行结束: " + index); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 方法一:isTerminated * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> sleepMethod(index)); } pool.shutdown(); while (!pool.isTerminated()){ Thread.sleep(1000); System.out.println("还没停止。。。"); } System.out.println("全部执行完毕"); } }上述代码处理逻辑在主线程中进行循环判断,全部任务是否已经完成。
package pool; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @堆代码 duidaima.com */ public class BaiLiIsShutdownThreadPoolDemo { /** * 创建一个最大线程数15的线程池 */ public static ThreadPoolExecutor pool = new ThreadPoolExecutor( 10, 15, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); /** * 线程执行方法,随机等待0到10秒 */ private static void sleepMethod(int index){ try { long sleepTime = new Double(Math.random() * 10000).longValue(); Thread.sleep(sleepTime); System.out.println("当前线程执行结束: " + index); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 方法二:getCompletedTaskCount * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> sleepMethod(index)); } //当线程池完成的线程数等于线程池中的总线程数 while (!(pool.getTaskCount() == pool.getCompletedTaskCount())) { System.out.println("任务总数:" + pool.getTaskCount() + "; 已经完成任务数:" + pool.getCompletedTaskCount()); Thread.sleep(1000); System.out.println("还没停止。。。"); } System.out.println("全部执行完毕"); } }上述代码处理逻辑还是一样在主线程循环判断,主要就两个方法:
缺点 :使用这种判断存在很大的限制条件;必须确定在循环判断过程中没有新的任务产生。
package pool; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @堆代码 duidaima.com */ public class BaiLiIsShutdownThreadPoolDemo { /** * 创建一个最大线程数15的线程池 */ public static ThreadPoolExecutor pool = new ThreadPoolExecutor( 10, 15, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); /** * 线程执行方法,随机等待0到10秒 */ private static void sleepMethod(int index){ try { long sleepTime = new Double(Math.random() * 10000).longValue(); Thread.sleep(sleepTime); System.out.println("当前线程执行结束: " + index); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 方法三:CountDownLatch * @throws Exception */ public static void main(String[] args) throws Exception { //计数器,判断线程是否执行结束 CountDownLatch taskLatch = new CountDownLatch(10); for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> { sleepMethod(index); taskLatch.countDown(); System.out.println("当前计数器数量:" + taskLatch.getCount()); }); } //当前线程阻塞,等待计数器置为0 taskLatch.await(); System.out.println("全部执行完毕"); } }优缺点分析
package pool; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @堆代码 duidaima.com */ public class BaiLiIsShutdownThreadPoolDemo { /** * 创建一个最大线程数15的线程池 */ public static ThreadPoolExecutor pool = new ThreadPoolExecutor( 10, 15, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); /** * 线程执行方法,随机等待0到10秒 */ private static void sleepMethod(int index){ try { long sleepTime = new Double(Math.random() * 10000).longValue(); Thread.sleep(sleepTime); System.out.println("当前线程执行结束: " + index); } catch (InterruptedException e) { e.printStackTrace(); } } private static int taskNum = 0; //计数器 /** * 方法四:公共计数 * @throws Exception */ public static void main(String[] args) throws Exception { Lock lock = new ReentrantLock(); for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> { sleepMethod(index); lock.lock(); taskNum++; lock.unlock(); }); } while(taskNum < 10) { Thread.sleep(1000); System.out.println("还没停止。。。当前完成任务数:" + taskNum); } System.out.println("全部执行完毕"); } }这种实现其实就是通过加锁计数,然后循环判断。
缺点 :和CountDownLatch相比,一样需要知道线程数目,但是代码实现比较麻烦。
package pool; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @堆代码 duidaima.com */ public class BaiLiIsShutdownThreadPoolDemo { /** * 创建一个最大线程数15的线程池 */ public static ThreadPoolExecutor pool = new ThreadPoolExecutor( 10, 15, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); /** * 线程执行方法,随机等待0到10秒 */ private static void sleepMethod(int index){ try { long sleepTime = new Double(Math.random() * 10000).longValue(); Thread.sleep(sleepTime); System.out.println("当前线程执行结束: " + index); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 方法五:Future * @throws Exception */ public static void main(String[] args) throws Exception { Future future = pool.submit(() -> sleepMethod(1)); while (!future.isDone()){ Thread.sleep(1000); System.out.println("还没停止。。。"); } System.out.println("全部执行完毕"); } }优缺点分析
package pool; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 五种判断线程池任务执行完成的方式 * @堆代码 duidaima.com */ public class BaiLiIsShutdownThreadPoolDemo { /** * 创建一个最大线程数15的线程池 */ public static ThreadPoolExecutor pool = new ThreadPoolExecutor( 10, 15, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); /** * 线程执行方法,随机等待0到10秒 */ private static void sleepMethod(int index){ try { long sleepTime = new Double(Math.random() * 10000).longValue(); Thread.sleep(sleepTime); System.out.println("当前线程执行结束: " + index); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 方法一:isTerminated * @param args * @throws InterruptedException */ public static void isTerminatedTest(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> sleepMethod(index)); } pool.shutdown(); while (!pool.isTerminated()){ Thread.sleep(1000); System.out.println("还没停止。。。"); } System.out.println("全部执行完毕"); } /** * 方法二:getCompletedTaskCount * @param args * @throws InterruptedException */ public static void completedTaskCountTest(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> sleepMethod(index)); } //当线程池完成的线程数等于线程池中的总线程数 while (!(pool.getTaskCount() == pool.getCompletedTaskCount())) { System.out.println("任务总数:" + pool.getTaskCount() + "; 已经完成任务数:" + pool.getCompletedTaskCount()); Thread.sleep(1000); System.out.println("还没停止。。。"); } System.out.println("全部执行完毕"); } /** * 方法三:CountDownLatch * @throws Exception */ public static void countDownLatchTest(String[] args) throws Exception { //计数器,判断线程是否执行结束 CountDownLatch taskLatch = new CountDownLatch(10); for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> { sleepMethod(index); taskLatch.countDown(); System.out.println("当前计数器数量:" + taskLatch.getCount()); }); } //当前线程阻塞,等待计数器置为0 taskLatch.await(); System.out.println("全部执行完毕"); } private static int taskNum = 0; /** * 方法四:公共计数 * @throws Exception */ public static void countTest(String[] args) throws Exception { Lock lock = new ReentrantLock(); for (int i = 0; i < 10; i++) { int index = i; pool.execute(() -> { sleepMethod(index); lock.lock(); taskNum++; lock.unlock(); }); } while(taskNum < 10) { Thread.sleep(1000); System.out.println("还没停止。。。当前完成任务数:" + taskNum); } System.out.println("全部执行完毕"); } /** * 方法五:Future * @throws Exception */ public static void futureTest(String[] args) throws Exception { Future future = pool.submit(() -> sleepMethod(1)); while (!future.isDone()){ Thread.sleep(1000); System.out.println("还没停止。。。"); } System.out.println("全部执行完毕"); } }