在重写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回答

悟空

2020-03-23

是执行的太快了,把任务都执行完了

改成这样就行:

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("恢复了");
}

1
1
冰棍儿zzz
非常感谢!
2020-03-27
共1条回复

悟空

2020-03-23

标志位应该加上volatile,可以保证可见

1
2
冰棍儿zzz
我在问题中把我代码贴出来,请老师分析一下
2020-03-23
共2条回复

深度解密Java并发工具,精通JUC,成为并发多面手

JUC全方位讲解,构建并发工具类知识体系

1599 学习 · 573 问题

查看课程