线程停止和同步

发布于 2024-10-14 08:31:47 字数 294 浏览 5 评论 0原文

我正在读一本书,其中说不要使用这样的代码:

private volatile Thread myThread;

....

myThread.stop();

相反,应该使用:

if (myThread != null ) {

 Thread dummy = myThread;

 myThread = null;

 dummy.interrupt();


}

不幸的是,这个主题没有进一步阐述......有人可以向我解释一下吗?

I'm reading a book which says not to use such a code:

private volatile Thread myThread;

....

myThread.stop();

Instead one should use:

if (myThread != null ) {

 Thread dummy = myThread;

 myThread = null;

 dummy.interrupt();


}

Unfortunately the subject is not elaborated any further... Could someone explain me this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

白首有我共你 2024-10-21 08:31:47

stop() 已弃用。永远不要、永远不要使用 stop()。您可以使用 java 并发< /a> 相反。

来自 Javadoc :

这种方法本质上是不安全的。使用 Thread.stop 停止线程会导致它解锁所有已锁定的监视器(这是未经检查的 ThreadDeath 异常向上传播堆栈的自然结果)。如果先前受这些监视器保护的任何对象处于不一致的状态,则损坏的对象将对其他线程可见,从而可能导致任意行为。 stop 的许多用法应替换为仅修改某些变量以指示目标线程应停止运行的代码。目标线程应该定期检查该变量,如果该变量指示它将停止运行,则以有序的方式从其 run 方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。

请查看 Java 并发实践第 7 章(取消和关闭)

stop() is deprecated. Never never and never use stop(). You can use java concurrency instead.

From Javadoc :

This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.

Have a look at Java Concurrency in Practice chapter 7 (Cancellation and Shutdown)

纵山崖 2024-10-21 08:31:47

您可以找到关于为什么不使用 stop() 方法的好答案 此处。您可以保存一个布尔变量并使用该变量无限循环,而不是使用此方法:

public class MyRunnable extends Runnable {
    public volatile boolean keepRunning = true;
    public void run() {
        while (keepRunning) {
            ... // do what you have to do
        }
    }
}

一旦决定完成,您只需将 keepRunning 变量设置为 false。然后你的线程将:
- 完成剩余步骤
- 终止

就像您以受控方式完成工作一样,不要使用不安全的 stop() 方法。

You can find a great answer on why not to use the stop() method here. Instead of using this method you can hold a boolean variable and loop infinitely using this variable:

public class MyRunnable extends Runnable {
    public volatile boolean keepRunning = true;
    public void run() {
        while (keepRunning) {
            ... // do what you have to do
        }
    }
}

Once you decide to finish, you just have to set the keepRunning variable to false. Your thread will then:
- finish the remaining steps
- terminate

Like that you finish your work in a controlled manner and don't use the unsafe stop() method.

热风软妹 2024-10-21 08:31:47

每个人都提供了关于为什么不调用 Thread.stop() 的重要信息。

Sergey 的评论修复了我提供的有关interrupt() 处理的错误信息。我更喜欢使用信号标志,就像 lewap 的答案一样。正如 Sergey 所说,interrupt() 的目的是唤醒处于阻塞操作的线程。如果你的线程没有调用任何阻塞操作,那么interrupt()实际上不会终止线程。不过,您的线程可以调用 isInterrupted() 来查看是否已调用中断(基本上是一个信号标志)。

回到你书中的例子,我不喜欢它。

if (myThread != null ) {

    Thread dummy = myThread;

    myThread = null;

    dummy.interrupt();

}

在此示例中没有充分的理由复制到虚拟变量。你感到困惑是对的。

本书作者可能正在考虑尝试阻止其他线程同时尝试中断同一线程,但中断代码不是线程安全的(“检查是否为 null 并设置为 null”操作不是原子操作),因此编写虚拟分配会搅浑水,而不会增加实际的线程安全性。

Everyone has given great information on why not to call Thread.stop().

Sergey's comment fixed the incorrect information I gave about interrupt() handling. I prefer to use a signal flag, like in lewap's answer. Like Sergey's said, interrupt() is for the purpose of waking up a thread that's in a blocked operation. If your thread doesn't call any blocking operations, then interrupt() won't actually terminate the thread. Your thread though can call isInterrupted() to see if interrupt has been called (a signal flag, basically).

Going back to your book's example, I don't like it.

if (myThread != null ) {

    Thread dummy = myThread;

    myThread = null;

    dummy.interrupt();

}

There's no good reason to copy to a dummy variable in this example. You are right to be confused.

The book authors might be thinking about trying to prevent other threads from simultaneously attempting to interrupt the same thread, but that interruption code is not thread safe (the "check if null and set to null" operation is not atomic), so writing the dummy assignment is muddying the waters without adding actual thread safety.

小嗷兮 2024-10-21 08:31:47

Thread.stop 已弃用,不应使用(更多信息 在这里)。

示例代码似乎取消了对“myThread”的引用,然后发出中断信号。假设“myThread”是对线程的唯一引用,并且线程中运行的代码正在正确处理中断请求(而不是忽略它们),则当“if (myThread != null)”出现时,线程将结束并有资格进行垃圾回收。 " 代码块完成。

Thread.stop is deprecated and should not be used (more info here).

The example code appears to nullify the reference to "myThread" and then signal for it to interrupt. Assuming "myThread" was the only reference to your thread and the code running in the thread is handling interrupt requests properly (and not ignoring them), the thread would end and be eligible for garbage collection when the "if (myThread != null)" code block completes.

药祭#氼 2024-10-21 08:31:47

尽管 Thread.stop 已被弃用。了解使用 Thread.stop 可以绕过 copmiler 检查异常控制也很有用。例如,

public void doSomething(){
    Thread.currentThread().stop(new IOException());
}

这将抛出 IOException。 IOException 是一个已检查的已检查异常,编译器通常会强制客户端捕获或让该方法抛出它。这里 doSomething 抛出一个未经检查的 IOException

Despite the fact that Thread.stop is deprecated. It is also useful to know that with Thread.stop you can circumvent copmiler checked exception control. For example,

public void doSomething(){
    Thread.currentThread().stop(new IOException());
}

That will throw an IOException. An IOException is a checked checked exception and the compiler normally will force the client to catch or let the method throw it. Here doSomething throws an unchecked IOException

烟织青萝梦 2024-10-21 08:31:47

除了 @Paweloque 所建议的(这是一种完美的方法)之外,还有另一种替代方法可以替代使用 stop() 建议 此处

错误方法:

假设您的小程序包含以下启动、停止和运行方法:

private Thread blinker;

public void start() {
    blinker = new Thread(this);
    blinker.start();
}

public void stop() {
    blinker.stop();  // UNSAFE!
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (true) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

正确方法 您可以通过将小程序的停止和运行方法替换为以下内容

来避免使用 Thread.stop:
私有易失性线程信号灯;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

In addition to what @Paweloque has suggested (which is a perfect way), there is another alternative to using stop() suggested here

The Wrong Way:

Suppose your applet contains the following start, stop and run methods:

private Thread blinker;

public void start() {
    blinker = new Thread(this);
    blinker.start();
}

public void stop() {
    blinker.stop();  // UNSAFE!
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (true) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

The Correct Way

You can avoid the use of Thread.stop by replacing the applet's stop and run methods with:
private volatile Thread blinker;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文