【问题标题】:Why does adding a synchronized block around this code change program ouput?为什么在此代码周围添加同步块会更改程序输出?
【发布时间】:2022-01-27 22:30:29
【问题描述】:
class Demo extends Thread{
    Test x;
    String name;
    String task;

    public Demo(String name, String task, Test p){
        this.name = name;
        this.task = task;
        x = p;
    }

    public void run(){
        synchronized (x) {
            x.message(name, task); 
        } 
    }



    public static void main(String[] args) {
        Test t = new Test();

        Demo d = new Demo("Jack", "Cutting",t);
        Demo d1 = new Demo("Jacoe", "Cooking",t);
        Demo d2 = new Demo("Bob", "Cleaning",t);
        d.start();
        d1.start();
        d2.start();

    }
    
}

class Test{
    void message(String name, String task){

        System.out.println(name);
        try{
            Thread.sleep(5000);
        }catch(Exception e){

        }
        System.out.println(task);

    }

}

这是我创建的一个简单程序,用于在 java 中练习多线程和同步。我想知道是否有人可以向我解释为什么从 public void run() 方法中删除同步块时输出不同?

有: With synchronized block

没有: Without synchronized block

【问题讨论】:

标签: java multithreading synchronization synchronized


【解决方案1】:

程序启动线程。操作系统必须在它们运行时进行调度,这似乎是任意的。然后不锁定线程可能会交错它们的操作。

在同步情况下,所有线程的运行方法都在同一个对象上同步,因此一次只能执行其中一个。不能保证它们中的哪一个先出现,调度程序可以选择它想要的任何一个。在您的情况下,它在第二个线程之前选择了第三个线程。

在任何情况下,各个输出行都不会交错,因为打印流是同步的。

【讨论】:

    【解决方案2】:

    输出从不确定地排序或保证是相同的顺序。它始终是“未定义的;系统可以按照它最终执行的任何顺序执行它。”

    【讨论】:

      【解决方案3】:

      synchronized 类似于 c# 中的lock 语句

      只有一个线程可以同时进入synchronized块。
      其他线程必须在synchronized 块前面等待。

      synchronized 的总运行时间应为 15 秒。
      总运行时间应该是 5 秒,因为所有 3 个线程同时运行。

      【讨论】:

        猜你喜欢
        • 2012-10-02
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        • 1970-01-01
        • 2017-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多