简体   繁体   English

为什么这个简单的Java同步代码块示例根据锁定的对象为我提供不同的输出?

[英]Why is this simple Java synchronized code block example giving me different output, depending on which object I lock on?

Ok, so I am trying to learn multi-threading. 好的,所以我正在尝试学习多线程。 I am reading a book and I came across this example for synchronized code blocks: 我正在读一本书,遇到了有关同步代码块的以下示例:

class CallMe {
    void call(String msg) {
        System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
        System.out.println("]");
    }
}

class Caller implements Runnable {

    String msg;
    CallMe target;
    Thread t;

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

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

public class Scrap {
    public static void main(String[] args) {
        CallMe target = new CallMe();
        Caller ob1 = new Caller( target, "Hello");
        Caller ob2 = new Caller( target, "Synchronized" );
        Caller ob3 = new Caller( target, "World");

        try {
            ob1.t.join();
            ob2.t.join();
            ob3.t.join();
        } catch (Exception e) {
            System.out.println("Interrupted");
        }
    }
}

I got the following output from this: 我从中得到以下输出:

[Hello]
[World]
[Synchronized]

Then, since I have done some tutorials online, I know that it is good style (or was told this) to create an instance of Object just for locking. 然后,由于我已经在线上完成了一些教程,所以我知道创建一个仅用于锁定的Object实例是一种很好的风格(或被告知)。 So, I did this and the Caller class became: 因此,我这样做了, Caller类变成了:

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

    private Object lock = new Object();

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

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

I was a little surprised when I got this as output: 当我得到这个输出时,我有些惊讶:

[Synchronized[Hello[World]
]
]

Of course, this is output where interleaving has taken place and it is not correct. 当然,这是在发生交织的地方输出的,这是不正确的。 My question is why did this happen? 我的问题是为什么会这样? I thought that making the lock Object would give me the same results. 我认为制作锁定Object会给我相同的结果。 Why did it (or why would it) not give me the same output? 为什么它(或为什么会)不给我相同的输出? I thought that creating the Object instance was good style and would work the same in this case, and to be honest I can't see why it would be different locking on "target" versus "lock". 我以为创建Object实例是一种好的样式,并且在这种情况下可以使用相同的方法,老实说,我不明白为什么锁定“目标”和“锁定”会有所不同。 I guess what I mean to ask is, why does locking on one certain item in this case cause the program to be correct and locking on the other makes it wrong? 我想问的意思是,为什么在这种情况下锁定某个项目会导致程序正确,而锁定另一项却导致程序出错?

Each instance of Caller locks on a different instance of lock . Caller每个实例都在不同的lock实例上lock I think you have to synchronize on shared instances. 我认为您必须在共享实例上进行synchronize Making the lock into a static member would share the same instance across all threads. lock设为static成员将在所有线程之间共享同一实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 Java 在两个不同的环境中给我两个不同的错误,即使(简单的)代码是相同的? - Why Java is giving me two different errors in two different envirnonments, even though the (simple) code is the same? Java 同步块:锁定块直到 object 实例化 - Java synchronized block: Lock block until object instantiated 具有不同类的同步块作为锁 - synchronized block with different class as lock 访问同步方法时,为什么我的线程给我这个输出? - Why are my threads giving me this output when accessing a synchronized method? Java的“同步”块是否锁定对象引用或值? - Does Java `synchronized` block lock on Object reference, or value? 为什么我的Java Morse代码翻译器给我错误的输出? - Why is my Java Morse Code translator giving me the wrong output? 为什么这些同步方法不断给我不同的输出? - Why do these synchronized methods keep giving me different outputs? 用于显示java synchronized块如何工作的示例代码 - example code to show how java synchronized block works 同步线程一个简单的产生reduce问题我看不懂。 为什么同步块内的 Thread.sleep 使它工作不同? - synchronized thread a simple produce reduce problem I can not understand. why Thread.sleep inside synchronized block makes it work different? 我可以访问Java中同步块使用的锁吗? - Can I access the Lock used by a synchronized block in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM