在重写runnable的run方法时,如果不休眠的情况,就会出现标志位不可见的情况
来源:3-8 钩子方法

冰棍儿zzz
2020-03-23
在重写runnable的run方,就会出现法时,如果不休眠,就会出现标志位不可见的情况,我请问一下老师,出现这种情况的原因。
我加上了volatile,他依然会在打印恢复了之后就不在打印。而一旦我在任务中加上sleep的代码,就会继续打印。
public class MyThreadPool extends ThreadPoolExecutor {
//是否暂停
private volatile boolean isPause = false;
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void resume() {
lock.lock();
try {
isPause = false;
condition.signalAll();
} finally {
lock.unlock();
}
}
public void pause() {
lock.lock();
try {
isPause = true;
} finally {
lock.unlock();
}
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
lock.lock();
try {
while (isPause) {
condition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
MyThreadPool threadPool = new MyThreadPool(10, 20, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
Runnable runnable = () -> System.out.println("执行了");
for (int i = 0; i < 10000; i++) {
threadPool.execute(runnable);
}
Thread.sleep(1500);
threadPool.pause();
System.out.println("暂停了");
Thread.sleep(1500);
threadPool.resume();
System.out.println("恢复了");
}
}
2回答
-
是执行的太快了,把任务都执行完了
改成这样就行:
public static void main(String[] args) throws InterruptedException {
MyThreadPool threadPool = new MyThreadPool(10, 20, 10, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
Runnable runnable = () -> System.out.println("执行了");
for (int i = 0; i < 100000; i++) {
threadPool.execute(runnable);
}
Thread.sleep(500);
threadPool.pause();
System.out.println("暂停了");
Thread.sleep(500);
threadPool.resume();
System.out.println("恢复了");
}112020-03-27 -
悟空
2020-03-23
标志位应该加上volatile,可以保证可见
122020-03-23
相似问题