提问者:小点点

为什么在这个代码周围添加一个同步块会改变程序输出?


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()方法中删除同步块时,为什么输出不同?

带:带同步块

无:无同步块


共3个答案

匿名用户

程序启动线程。操作系统必须计划何时运行,这似乎是任意的。然后,在不锁定的情况下,线程可能会交错其动作。

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

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

匿名用户

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

匿名用户

同步就像c#中的lock语句

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

同步的总运行时间应为15秒
由于所有3个线程同时运行,因此没有的总运行时间应为5秒。