java 停止线程并再次开始在黑莓中给出 IllegalThreadStateException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13538668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:08:56  来源:igfitidea点击:

Stop thread and again start giving IllegalThreadStateException in blackberry

javamultithreadingblackberryjava-me

提问by AnkitRox

I am getting IllegalThreadStateExceptionexception when using following code: I have already started this thread once(by using thread.start()) and again trying to start it at another place, so used following code:

IllegalThreadStateException使用以下代码时出现异常:我已经启动了该线程一次(通过使用thread.start())并再次尝试在另一个地方启动它,因此使用了以下代码:

thread.interrupt();
thread.start();

But thread.start()is throwing IllegalThreadStateException.

而是thread.start()在扔IllegalThreadStateException

What should I use to solve it?

我应该用什么来解决它?

回答by Nate

Threadobjects are only meant to be started once. If you need to stop/interrupt a Thread, and then want to start it again, you should create a new instance, and call start()on it:

Thread对象只能启动一次。如果您需要停止/中断 a Thread,然后想再次启动它,您应该创建一个新实例,并调用start()它:

thread.interrupt();  // if you need to make sure thread's run() method stops ASAP
thread = new MyThreadSubclass();
thread.start();

From the API docs

来自 API 文档

IllegalThreadStateException- if the thread was already started.

IllegalThreadStateException- 如果线程已经启动。

I know it's not 100% clear that you can't call start()again, even if you previously called interrupt(), but that's the way it works.

我知道不能 100% 清楚您不能start()再次调用,即使您之前调用过interrupt(),但它就是这样工作的。

If you look at the API docs for standard Java, this issue is more clear.

如果您查看标准 JavaAPI 文档,这个问题就更清楚了。

回答by Vit Khudenko

In addition to Nate's answer.

除了内特的回答。

AnkitRox states in his comment:

AnkitRox 在他的评论中指出:

Thanks Nate. I was also trying your method. But the problem occurred at that time was, it was start a new thread for the new instance and previous thread was also working.

谢谢内特。我也在尝试你的方法。但是当时出现的问题是,它为新实例启动了一个新线程,并且以前的线程也在工作。

So it looks like the problem is "the thread is still running even if I called interrupt on it". Consider this sample (it is ugly, but enough to show the main idea):

所以看起来问题是“即使我调用了中断,线程仍在运行”。考虑这个示例(它很丑,但足以显示主要思想):

final Thread t = new Thread(new Runnable() {
    public void run() {
        while (true) {
            for (int i = 0; i < 100000000; i++); // simulate some action
            System.out.println("hi, interrupted = " 
                    + Thread.currentThread().isInterrupted());
        }
    }
});
t.start();
new Timer(true).schedule(
    new TimerTask() {
        public void run() {
            t.interrupt();
        }
    },
    1000 // 1 second delay
);

Note, the thread continues to run even after interrupt()has been called. The produced output is:

请注意,该线程即使在interrupt()被调用后仍会继续运行。产生的输出是:

hi, interrupted = false
hi, interrupted = true
hi, interrupted = true
hi, interrupted = true
...
hi, interrupted = true

Actually the programm never stops unless closed forcefully. So what then the interrupt()does? It just sets the interrupted flagto true. After interrupt()has been called the Thread.currentThread().isInterrupted()starts to return false. And that's all.

实际上,除非强行关闭,否则程序永远不会停止。那么interrupt()呢?它只是将中断标志设置true。之后interrupt()被称为Thread.currentThread().isInterrupted()开始返回false。就这样。

Another case is if interrupt()is called while the thread is blocked in an invocation of one of the methods that throw InterruptedException, then that method will return throwing the InterruptedException. And if thread's code just "eats" that exception, then the thread will still continue running, consider a sample:

另一种情况是,如果interrupt()在调用 throw 的方法之一中阻塞线程时调用InterruptedException,则该方法将返回引发InterruptedException. 如果线程的代码只是“吃掉”那个异常,那么线程仍然会继续运行,考虑一个示例:

final Thread t = new Thread(new Runnable() {
    public void run() {
        while (true) {
            System.out.println("hi, interrupted = " 
                    + Thread.currentThread().isInterrupted());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                System.out.println("got InterruptedException");
            }
        }
    }
});
t.start();
new Timer(true).schedule(
    new TimerTask() {
        public void run() {
            t.interrupt();
        }
    },
    1000 // 1 second delay
);

Note, the thread continues to run even after interrupt()has been called. The produced output is:

请注意,该线程即使在interrupt()被调用后仍会继续运行。产生的输出是:

hi, interrupted = false
got InterruptedException
hi, interrupted = false
hi, interrupted = false
...
hi, interrupted = false

Note, this time interrupted = falseeven after interrupt()has been called. This is because whenever InterruptedExceptionis caught, the interrupted flagis reset to false.

注意,这一次interrupted = false即使在interrupt()被调用之后。这是因为无论何时InterruptedException被捕获,中断标志都会重置为false

In Java stopping a thread is cooperativemechanism. Meaning it can not be done without cooperation from the thread itself. Here is the fixed version of the above sample:

在 Java 中停止线程是协作机制。这意味着没有线程本身的合作就无法完成。这是上述示例的固定版本:

final Thread t = new Thread(new Runnable() {
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("hi, interrupted = " 
                    + Thread.currentThread().isInterrupted());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                System.out.println("we've been interrupted");
                // restore the interrupted flag
                Thread.currentThread().interrupt();
            }
        }
    }
});
t.start();
new Timer(true).schedule(
    new TimerTask() {
        public void run() {
            t.interrupt();
        }
    },
    1000 // 1 second delay
);

So the correct approach should be to periodically check the interrupted flag. And if interrupted status is detected then just return ASAP. Another common option is not to use Thread.interrupt()at all, but some custom boolean instead.

所以正确的做法应该是定期检查中断标志。如果检测到中断状态,则尽快返回。另一个常见的选择是根本不使用Thread.interrupt(),而是使用一些自定义布尔值