【问题标题】:synchronization usage java [duplicate]同步使用java [重复]
【发布时间】:2021-12-12 08:50:41
【问题描述】:

如果我删除 "synchronized" ,则不会打印 "Wait 3 seconds and exit" 。

但如果我添加“System.out.println(getStarted());”或 "System.out.println(123);"... 在 while 循环中,将打印 "Wait 3 seconds and exit"。

我想知道为什么????

public class Consistent {
    static boolean started = false;

    public synchronized static void setStarted() { //delete synchronized
        started = true;
    }

    public synchronized static boolean getStarted() {//delete synchronized 
        return started;
    }

    public static void main(String[] args) {
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                }
                setStarted();
                System.out.println("started set to true");
            }
        });
        thread1.start();

        while (!getStarted()) {
            // wait until started
           // System.out.println(getStarted());


        }

        System.out.println("Wait 3 seconds and exit");
    }

}

【问题讨论】:

    标签: java multithreading synchronized


    【解决方案1】:

    如果没有synchronized,则无法保证一个线程所做的修改将对在同一对象上同步的其他线程可见。这是因为 Java 内存模型定义了编译器和运行时如何重新排列对变量的读/写,以及如何优化事物。 while 循环可能会获得一次 started 的值并保留它。使用synchronized,一个线程对变量所做的修改对所有其他线程都是可见的。

    当您将 println 移动到 while 循环中时,您会引入额外的同步,因为 println 在内部使用 synchronized 内存访问。

    这可能会有所帮助:http://tutorials.jenkov.com/java-concurrency/java-memory-model.html

    【讨论】:

    • are visible to all other threads. 小修改:Java 内存模型只保证synchronized 在同一对象上的线程可见性。如果一个变量是用 synchronized 写入的,但在没有它的情况下读取,则不会发生这样的保证。所以它不是“所有线程”,而是只有在读取时正确同步的线程。
    猜你喜欢
    • 1970-01-01
    • 2021-10-26
    • 2011-09-20
    • 2016-05-08
    • 2014-02-07
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多