当前位置: 首页 > 知识库问答 >
问题:

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

松钊
2023-03-14
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个答案

柯立果
2023-03-14

同步就像c#中的lock语句

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

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

曹泉
2023-03-14

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

齐高阳
2023-03-14

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

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

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

 类似资料:
  • 我试图做一个函数,返回数组的长度,但函数总是返回8

  • 问题内容: 范例1: 输出为: 范例2: 输出: 我只是不明白为什么将saySomething设为非静态会导致第二次调用saySomething调用Cow版本而不是Animal版本。我的理解是, 这两种情况都是输出。 问题答案: 静态方法在编译时绑定到其类,并且不能多态使用。在Animal上声明“静态”方法时,该方法永远绑定到Animal类,并且不能被覆盖。静态方法绑定到Class对象,而不是Cl

  • 问题内容: 我创建了一个html错误页面。它有2行显示错误。第二行链接到主页。为了使两行保持在中心,我创建了一个顶层并将网格的每一行都设为a 。我注意到,如果我用于第二行,则链接周围没有任何空格,但是如果删除,该空格将被添加,即html从变为。 如果删除属性,为什么会添加空格? 码 html CSS 问题答案: 这是因为flexbox删除或元素之间的默认空白。 这是没有flexbox的代码,其中有

  • 问题内容: 我已经修改了一些Go代码,以解决与我姐夫玩的电子游戏有关的我的好奇心。 本质上,下面的代码模拟了游戏中与怪物的互动,以及他期望他们在失败后掉落物品的频率。我遇到的问题是,我希望这样的一段代码非常适合并行化,但是当我并发添加时,完成所有模拟所花费的时间往往会使原始代码的速度降低4-6倍没有并发。 为了使您更好地理解代码的工作方式,我有三个主要功能:交互功能,它是玩家和怪物之间的简单交互。

  • 该程序应该使用int 0x10在ASCII中打印一个具有给定字符的金字塔,3行的预期结果(下面代码中使用的数量)将是: A. a a a a a 要编译和运行代码,我使用nasm编译它,然后使用qemu进行仿真: 然而,程序get无法打印所有ASCII值。此外,如果有任何针对nasm代码的调试器,可以让您逐行运行,允许您检查寄存器值,这对学习也很有帮助。

  • 令牌“if”的语法错误(应在此令牌之后 谢谢你的建议!