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

Java中的同步代码输出顺序错误

王亮
2023-03-14

我目前正在学习Java,我已经达到同步的主题。

由于某些原因,下面的代码(基于完全参考JAVA-赫伯特·席尔特第七版,第239-240页的代码)没有给出所需的输出。

代码:

package package1;
class Call{
    synchronized public void call(String msg){
        System.out.print("[" + msg);
        try{
            Thread.sleep(100);
        }catch (InterruptedException e){
            System.out.println("Interrupted Exception Caught");
        }
        System.out.println("]");
    }
}

class CallMe implements Runnable{
    String msg;
    Call target;
    Thread t;

    public CallMe(Call targ, String message){
        target = targ;
        msg = message;
        t = new Thread(this);
        t.start();
    }

    public void run(){
        target.call(msg);
    }
}

public class Synchronization {
    public static void main(String[] args) {
        Call target = new Call();
        CallMe obj1 = new CallMe(target, "Hello");
        CallMe obj2 = new CallMe(target, "Synchronized");
        CallMe obj3 = new CallMe(target, "World");

        try{
            obj1.t.join();
            obj2.t.join();
            obj3.t.join();
        }catch (InterruptedException e){
            System.out.println("Interrupted Exception Caught");
        }
    }
}

所需输出:

[Hello]
[Synchronized]
[World]

实际输出(我在2013年底使用Macbook Pro上的Eclipse):

[Hello]
[World]
[Synchronized]

我已经读到,所有这些主题的输出都因计算机而异。

有人能解释一下为什么这行不通吗?

共有2个答案

易成天
2023-03-14

把彼得的答案背上一点。同步所做的就是防止事情变得疯狂。

在没有同步调用的情况下尝试这段代码,可以看到调用类可以命中。随心所欲地出去,不考虑其他物体。我得到这样的输出,删除了“synchronized”:

[Hello[World[Synchronized]
]
]

有了同步,你会得到你所看到的东西,。。但这并不能保证秩序。有时你会:

[Hello]
[World]
[Synchronized] 

有时你会:

[Hello]
[Synchronized]
[World]

一遍又一遍,你就会明白我的意思
要真正摆脱它,请尝试使用:

Thread.sleep(1);
李成礼
2023-03-14

因为不同的CallMe实例是并行调用的,您不能保证它们是按哪个顺序处理的。您唯一知道的是,Call.call(String)不会并行调用,因为此方法是同步

 类似资料:
  • 主要内容:1 什么是Java同步代码块,2 Java同步代码块的要点,3 Java同步代码块的语法,4 Java同步代码块的例子1,5 Java同步代码块的例子21 什么是Java同步代码块 同步代码块可用于对方法的任何特定资源执行同步。 假设您的方法中有50行代码,但是您只想同步5行,则可以使用synchronized代码块。 如果将方法的所有代码放在同步代码块中,它的效果与同步方法相同。 2 Java同步代码块的要点 同步代码块用于锁定任何共享资源的对象。 同步代码块的范围小于该方法。 3 

  • 问题内容: 我有一个奇怪的问题,如果可以解决,那就太好了。出于调试目的(以及其他一些目的),我在标准输出上编写了控制台Java应用程序的日志。在标准输出上写一些内容,在标准错误上打印一些错误,例如错误。问题是这两个没有完全同步,因此打印线的顺序并不总是正确的。我猜这是因为打印了很多东西,并且碰巧一个输出的缓冲区已满,所以其他输出在第一个输出刷新其缓冲区之前就已打印出来。 例如,我想这样写: 有时打

  • 本文向大家介绍解释如下代码的输出结果,并改造代码使得按顺序输出i相关面试题,主要包含被问及解释如下代码的输出结果,并改造代码使得按顺序输出i时的应答技巧和注意事项,需要的朋友参考一下

  • 在测试同步代码时,省略回调,Mocha将自动继续进行下一次测试。 describe('Array', function() { describe('#indexOf()', function() { it('should return -1 when the value is not present', function() { [1,2,3].indexOf(5).should.eq

  • myusername hi%cd/users/myusername/desktop/programming/hi/library/java/javavirtualmachines/jdk-15.0.1.jdk/contents/home/bin/java-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=localhost:5

  • 我试图做一个java程序,但我有一个问题与输出。