【问题标题】:Reentrant lock condition可重入锁条件
【发布时间】:2021-06-16 23:39:46
【问题描述】:

我想创建一个允许暂停和恢复线程的类 Suspender,但不幸的是,在调用 condition.signalAll() 之后什么也没发生。谁能告诉我,是什么原因?

public class Task extends Thread{

    private Suspender suspender;

    public boolean paused = false;

    public Task(Suspender suspender){
        this.suspender = suspender;
    }

    public void resumeThread(){
        suspender.resume(this);
    }

    public void run(){
        System.out.println("Pausing");
        paused = true;
        suspender.pause(this);
        System.out.println("Resumed");
    }
}

public class Suspender{

    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void pause(Task current) {
        try{
            lock.lock();
            while(current.paused){
                condition.await();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally{
            lock.unlock();
        }
    }

    public void resume(Task current) {
        try{
            lock.lock();
            current.paused = false;
            condition.signalAll();
        }finally{
            lock.unlock();
        }
    }

}

public class Start{

    public static void main(String args[]) throws Exception {
        Suspender suspender = new Suspender();

        Task t1 = new Task(suspender), t2 = new Task(suspender);
        t1.start();
        t2.start();

        TimeUnit.SECONDS.sleep(2);
        t1.resume();
        TimeUnit.SECONDS.sleep(2);
        t2.resumeThread();

        t2.join();
    }

}

【问题讨论】:

  • "我想创建一个允许随时暂停和恢复线程的类 Suspender" -- 你可以随心所欲,但你不会无需底层调度程序的合作即可获得它。你不能在你的线程之上实现它。
  • @JohnBollinger 你说的是 ScheduledExecutorService 吗?刚刚开始学习锁。
  • 不,@Razor,我说的是你的线程实现的线程调度程序。对于使用本机线程(即大多数线程)的 Java 实现,这是操作系统的一部分。
  • @JohnBollinger 好的,还有其他方法可以使用锁暂停和恢复线程吗?
  • 我应该澄清一下,@Razor:线程可以通过等待条件变量来使 它们自己暂停执行,正如您的代码所演示的那样,或者如果它们试图获取一个由不同线程持有的独占锁,以及许多其他可能性。但这些都不是一个笼统的、任意的“你想要的任何时间”。

标签: java multithreading locks


【解决方案1】:

您的主线程调用t1.resume(),但您的Task 类声明public void resume(Task current)。这是两种不同的方法。如果不同的方法具有不同的参数列表,Java 允许它们具有相同的名称。当您的主线程调用t1.resume() 时,它正在调用deprecated method of the Thread class,这将不起作用,因为线程从未被挂起。*


* 注意:suspended 与等待条件不同。

【讨论】:

    猜你喜欢
    • 2021-04-18
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多