放水
package thread; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; import java.util.concurrent.*; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class MyTestThreadPool extends ThreadPoolExecutor { public MyTestThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } public MyTestThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); } public MyTestThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); } public MyTestThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); } private final ReentrantLock lock = new ReentrantLock(); private Condition unpaused = lock.newCondition(); private boolean isPaused; @Override protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); lock.lock(); try { while (isPaused) { unpaused.await(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void pause() { lock.lock(); try { isPaused = true; } finally { lock.unlock(); } } public void resume() { lock.lock(); try { isPaused = false; //唤醒 unpaused.signalAll(); } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { MyTestThreadPool myTestThreadPool = new MyTestThreadPool( 10, 20, 10l, TimeUnit.SECONDS, new LinkedBlockingQueue<>() ); Runnable runnable = new Runnable() { @Override public void run() { System.out.println("正在放水"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }; System.out.println("开始上班,往水池放1000吨水"); for (int i = 0; i < 1000; i++) { myTestThreadPool.execute(runnable); } Thread.sleep(2000); myTestThreadPool.pause(); int num = myTestThreadPool.getQueue().size(); System.out.println("暂停放水"); System.out.println("中午回家吃饭,暂停放水,还剩" + num + "吨水"); Thread.sleep(2000); myTestThreadPool.resume(); System.out.println("下午上班,开始放水"); Thread.sleep(2000); myTestThreadPool.shutdown(); boolean shutdown = myTestThreadPool.isShutdown(); if (shutdown) { System.out.println("五点了开始停水 10后强制停水开始停水"); } boolean awaitTermination = myTestThreadPool.awaitTermination(10, TimeUnit.SECONDS); if (awaitTermination) { System.out.println("停水成功 水池没水了"); } else { System.out.println("启动强制停水"); myTestThreadPool.shutdownNow(); } } }
请问老师如何计算剩余水的数量 以及我的程序有哪些问题
16
收起
正在回答 回答被采纳积分+1
1回答
好帮手慕小蓝
2022-11-23 18:30:03
同学你好,同学的代码符合题目要求,逻辑清晰,书写规范,做的很棒。
同学代码中已经正确解决了剩余水量的问题,即使用getQueue().size()的方式获取当前队列中剩余任务数的方式。
由于awaitTermination方法并不会立即停止所有任务,所以在shutdownNow()方法前调用getQueue().size()获取剩余水量。修改过的代码如下:
public static void main(String[] args) throws InterruptedException { MyTestThreadPool myTestThreadPool = new MyTestThreadPool(10, 20, 10l, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); Runnable runnable = new Runnable() { @Override public void run() { System.out.println("正在放水"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }; System.out.println("开始上班,往水池放1000吨水"); for (int i = 0; i < 1000; i++) { myTestThreadPool.execute(runnable); } Thread.sleep(200); myTestThreadPool.pause(); int num = myTestThreadPool.getQueue().size(); System.out.println("暂停放水"); System.out.println("中午回家吃饭,暂停放水,还剩" + num + "吨水"); Thread.sleep(200); myTestThreadPool.resume(); System.out.println("下午上班,开始放水"); Thread.sleep(200); //为了防止在获取数量和关闭之间出现的误差,使用同步进行处理 Object o = new Object(); synchronized (o) { num = myTestThreadPool.getQueue().size(); myTestThreadPool.shutdown(); System.out.println("线程池关闭时剩余" + num); } boolean shutdown = myTestThreadPool.isShutdown(); if (shutdown) { System.out.println("五点了开始停水 10后强制停水开始停水"); } boolean awaitTermination = myTestThreadPool.awaitTermination(1, TimeUnit.SECONDS); if (awaitTermination) { System.out.println("停水成功 水池没水了"); } else { synchronized (o) { System.out.println("启动强制停水"); num = myTestThreadPool.getQueue().size(); System.out.println("当前剩余" + num); myTestThreadPool.shutdownNow(); } } }
由于同学代码中等待时间过长,无法体现强制关闭,所以需要将awaitTermination中的参数设置小一些。同时由于同学代码中采用抛出的方式,所以需要在异常信息前查看运行结果。运行的效果如下图:
祝学习愉快~
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星