放水
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中的参数设置小一些。同时由于同学代码中采用抛出的方式,所以需要在异常信息前查看运行结果。运行的效果如下图:

祝学习愉快~
2023版Java工程师
- 参与学习 人
- 提交作业 8790 份
- 解答问题 9886 个
综合就业常年第一,编程排行常年霸榜,北上广深月薪过万! 不需要基础,无需脱产即可学习,只要你有梦想,想高薪! 全新升级:技术栈升级(包含VUE3.0,ES6,Git)+项目升级(前后端联调与功能升级)
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星