简体   繁体   English

Java,多线程

[英]Java, Multithreading

I am learning Multithreading and Concurrency in Java on my own.我正在自己学习 Java 中的多线程和并发。 Please help me understand this piece of code.请帮助我理解这段代码。 I am creating a thread with a 'stop' boolean variable, the 'run' method loops continuously until the main thread sets the stop variable to true after sleeping for two seconds.我正在创建一个带有 'stop' 布尔变量的线程,'run' 方法不断循环,直到主线程在休眠两秒钟后将停止变量设置为 true。 However, I am observing this code runs in an infinite loop.但是,我观察到此代码在无限循环中运行。 What am I doing wrong here?我在这里做错了什么?

public class Driver {
    public static void main(String[] args) {
        ThreadWithStop threadWithStop = new ThreadWithStop();
        Thread thread = new Thread(threadWithStop);
        thread.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadWithStop.stopThread();
    }
}

class ThreadWithStop implements Runnable {

    private boolean stop;

    public ThreadWithStop() {
        this.stop = false;
    }

    public void stopThread() {
        this.stop = true;
    }

    public boolean shouldRun() {
        return !this.stop;
    }

    @Override
    public void run() {
        long count = 0L;
        while (shouldRun()) {
            count++;
        }
        System.out.println(count+"Done!");
    }
}

Well, it is not guaranteed to stop, but it might.好吧,不能保证停止,但可能会停止。 The change you made to the stop by calling stopThread() from the main thread is not guaranteed to be visible to the ThreadWithStop until you synchronize with it somehow.您通过从主线程调用stopThread()stop所做的更改不能保证对ThreadWithStop可见,直到您以某种方式与它同步。

One way to achieve this would be to protect access to the variable with the synchronized keyword - see eg the official Oracle tutorial on synchronized methods :实现此目的的一种方法是使用synchronized关键字保护对变量的访问 - 例如,请参阅有关同步方法的官方 Oracle 教程:

With the following changes, the change to stop is guaranteed to be visible.通过以下更改,可以保证stop更改是可见的。

class ThreadWithStop implements Runnable {

    private boolean stop;

    public ThreadWithStop() {
        this.stop = false;
    }

    public synchronized void stopThread() {
        this.stop = true;
    }

    public synchronized boolean shouldRun() {
        return !this.stop;
    }

    @Override
    public void run() {
        long count = 0L;
        while (shouldRun()) {
            count++;
        }
        System.out.println(count+"Done!");
    }
}

Because they share the same variable, and the 'main' thread have the copy of the variable 'stop', the 'thread' thread also have the copy of that.因为它们共享相同的变量,并且“主”线程拥有变量“停止”的副本,“线程”线程也拥有该变量的副本。 If you change the 'stop', it will not be noticed immediately by 'thread' thread.如果您更改“停止”,则“线程”线程不会立即注意到它。 We can use the keyword 'volatile', so if you change the 'stop', it will be noticed immediately.我们可以使用关键字'volatile',所以如果你改变'stop',它会立即被注意到。

private volatile boolean stop;

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

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