正在回答 回答被采纳积分+1
4回答
电磁护盾
2021-06-12 11:34:20
package practice2;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 演示每个任务执行前后放钩子函数
*/
public class PauseableThreadPool1 extends ThreadPoolExecutor {
public PauseableThreadPool1(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
public PauseableThreadPool1(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}
public PauseableThreadPool1(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
}
public PauseableThreadPool1(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;
//重写的方法,用来识别下方的标记位
//每一次执行任务之前,都会调用beforeExecute()方法,并且在这个方法中会去检查while (isPaused)这里是不是被标记为现在想暂停了,如果想暂停就
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
lock.lock();
//如果检测到是true了,说明我们想让它暂停了
try {
while (isPaused) {
//暂停之后,就用Condition来让线程进行休眠
unpaused.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
//暂停方法
private void pause() {
//用这个锁,必须加上try catch finally,否则可能出现这个锁永远无法释放
lock.lock();
try {
isPaused = true;
}finally {
lock.unlock();
}
}
//恢复方法,既然已经恢复,就让之前被暂停的那些给唤醒
public void resume() {
lock.lock();
try {
//然后把标记位设置回去,是false
isPaused = false;
//唤醒
unpaused.signalAll();
}finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
//创建一个可暂停线程池对象
PauseableThreadPool1 pauseableThreadPool = new PauseableThreadPool1(1, 1, 10l,
TimeUnit.SECONDS, new LinkedBlockingQueue<>());
//创建一个线程,打印信息
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
System.out.println("正在放水");
} catch (InterruptedException e) {
System.out.println("暂停放水中。。。。。。。。。");
}
}
};
System.out.println("上班啦,水池放入1000吨水");
//往线程池中添加1000个任务
for (int i = 0; i < 1000; i++) {
pauseableThreadPool.execute(runnable);
}
System.out.println(pauseableThreadPool.getQueue().size() + "<--------1");
//当它执行200毫秒之后,调用pause()方法,让它暂停
//Thread.sleep(200);
pauseableThreadPool.pause();
System.out.println("中午啦,回家吃饭啦,水池被暂停了 还剩" + pauseableThreadPool.getQueue().size() + "吨水");
System.out.println("线程池被暂停了");
/*//让线程池恢复
Thread.sleep(200);
pauseableThreadPool.resume();
System.out.println("线程池被恢复了");*/
}
}
java工程师2020版
- 参与学习 人
- 提交作业 9401 份
- 解答问题 16556 个
综合就业常年第一,编程排行常年霸榜,无需脱产即可学习,北上广深月薪过万 无论你是未就业的学生还是想转行的在职人员,不需要基础,只要你有梦想,想高薪
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星