简体   繁体   English

java synchronized线程澄清

[英]java synchronized Thread clarification

The answer for this program will have to be "Changing done" after 5 secs, but I get "Changing done" and "DONE". 这个程序的答案必须在5秒后完成“改变完成”,但我得到“改变完成”和“完成”。 I do not have the getDone method as synchronized. 我没有getDone方法同步。 Any ideas what am I doing for the thread to finish processing. 我有什么想法为线程完成处理。

public class Main {
    private static boolean done = false;
    private static int count;

    public static void main(String[] args)throws InterruptedException {
        new Thread(() -> {
            while (!getDone()) {
                count = count + 1;
            }
            System.out.println("DONE!!!!");
        }).start();
            Thread.sleep(5000);
        System.out.println("Changing done");
        synchronized (Main.class) {
            done = true;
        }
    }

    public static boolean getDone() {
        return done;
    }
}

If you don't synchronize access to done properly, it means your code may fail, ie the thread may not see the updated value. 如果不同步访问done正确的,这意味着你的代码可能会失败,即线程可能不会看到更新后的值。

It does not mean the value is guaranteed not visible unless synchronizing correctly. 除非正确同步,否则并不意味着保证值不可见。 So, in many cases the write to done is still visible (the fact that broken code still works in many cases makes concurrent programming harder). 因此,在许多情况下,写入done仍然可见(在许多情况下,破坏的代码仍然有效,这使得并发编程更加困难)。 It is just not guaranteed to work in every case. 它并不能保证在每种情况下都能正常工作。

I do not have the getDone method as synchronized. 我没有getDone方法同步。 Any ideas what am I doing for the thread to finish processing. 我有什么想法为线程完成处理。

As you mention, there is no explicit memory synchronization between the done as seen by your spinning thread and the main thread. 正如您所提到的,在旋转线程和主线程看到的done之间没有明确的内存同步。 Although the main thread crosses a write memory barrier when exiting the synchronized block, there is no explicit read memory barrier crossed by the spinning thread. 虽然主线程在退出synchronized块时穿过写入内存屏障,但是旋转线程没有明确的读取内存屏障。

However, there are many ways for a thread to see updated information. 但是,线程有很多方法可以查看更新的信息。 If the operating system swaps the thread out of its running processor, the cached memory may be lost so when the thread gets swapped back it, it will request done from central memory and will see the update. 如果操作系统将线程交换出正在运行的处理器,则缓存的内存可能会丢失,因此当线程被交换回来时,它将从中央内存请求done并将看到更新。

Also, although your example code doesn't show it, if you make calls to other synchronized methods (such as System.out.println() ) or cross other memory barriers (accessing another volatile field), then this will also cause done to be updated. 此外,虽然您的示例代码并没有表现出来,如果您对其他调用synchronized方法(如System.out.println()或其他交叉内存屏障(访问其他volatile场),那么这也将引起done到得到更新。

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

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