简体   繁体   English

如何使用wait()和notify()正确暂停线程

[英]How do I pause Threads properly with wait() and notify()

I want to have a class that starts a Thread and provides methods to pause and continue this Thread. 我想有一个启动Thread的类,并提供暂停和继续此Thread的方法。 My first approach was to have flag, which loops a sleep method as long as the value is true. 我的第一种方法是使用flag,只要值为true,就会循环一个sleep方法。 Something like : 就像是 :

public class Bot {
private Thread t ;
private boolean isPaused;

public Bot(){
    t = new Thread(new Runnable(){
        @Override
        public void run() {
            while (true) {
                System.out.println("Hi");


                while(isPaused){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    });

    t.start();
}
public void pauseBot(){
    isPaused = true;
}

public void continueBot(){
    isPaused = false;
}
}

But since the Thread is still running and wasting CPU, I dont find this to be a good solution. 但由于线程仍在运行并浪费CPU,我不认为这是一个很好的解决方案。 How would this look with wait() and notify(). 这看起来如何使用wait()和notify()。 I had a look at various tutorials about that topic but somehow I couldnt apply them to my issue. 我看了一下有关该主题的各种教程,但不知怎的,我无法将它们应用到我的问题中。

Everytime I tried it I either got IllegalMonitorStateException or the code stopped my whole application and not just the Thread I wanted to be stopped. 每次我尝试它时,我或者得到了IllegalMonitorStateException,或者代码停止了我的整个应用程序,而不仅仅是我想要停止的线程。

Another question I have is: How do prevent the Thread from beeing paused at a critical moment eg 我的另一个问题是:如何防止线程在关键时刻暂停,例如

Runnable r = new Runnable(){

    @Override
    public void run() {
        while(true){
            task1();
            task2();

            //Thread mustn't be stopped from here....
            task3();
            task4();
            task5();
            task6();
            task7();
            //... to here

            task8();
            task9();
            task10();
        }

    }

};

Because when task3() .... task7() deal with something that would expire while the Thread is paused there must be a way to let the Thread finish task7() until it pauses. 因为当task3().... task7()处理在Thread暂停时会过期的东西时,必须有一种方法让Thread完成task7()直到它暂停。

I hope you can help me with my issue. 我希望你能帮我解决我的问题。 Thanks in advance, Flo 提前谢谢,弗洛

So given this is your Thread class: 所以这是你的Thread类:

public class MyThread extends Thread
{

First, you need an lock object. 首先,您需要一个锁定对象。 This object can be everything, and if you use an existing object this takes less memory. 此对象可以是所有内容,如果使用现有对象,则占用的内存较少。 Also define a flag if the bot should be paused. 如果机器人应该暂停,也要定义一个标志。

    public Object lock = this;
    public boolean pause = false;

Now, define a pause() and continue() method for the thread. 现在,为线程定义pause()continue()方法。 This sets the pause flag. 这设置了pause标志。

    public void pause ()
    {
        pause = true;
    }

    public void continue ()
    {
        pause = false;

Here you need to wake up the thread. 在这里你需要唤醒线程。 Note the synchronized on the lock object so that you don't get an IllegalMonitorStateException . 请注意锁定对象上的synchronized,以便您不会收到IllegalMonitorStateException

        synchronized (lock)
        {
            lock.notifyAll();
        }
    }

No, define a method that automatically pauses the thread when it should be paused. 不,定义一个在应该暂停时自动暂停线程的方法。 You might call this at every moment when the thread can be paused. 您可以在线程暂停时随时调用此方法。

    private void pauseThread ()
    {
        synchronized (lock)
        {
            if (pause)
                lock.wait(); // Note that this can cause an InterruptedException
        }
    }

Now, you can define your thread in the run() method: 现在,您可以在run()方法中定义您的线程:

    public void run ()
    {
        task1();
        task2();

        pauseThread();

        task3();
        task4();
        task5();
        task6();
        task7();

        pauseThread();

        task8();
        task9();
        task10();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM