java - 实例同步

标签 java multithreading synchronized

我编写了一小段代码来理解同步 block 的概念:

public class ObjectLevelSynchronized {

    public void run() {
        synchronized(this) {
            try {
                System.out.println(Thread.currentThread().getName());
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + " Finished.");
            }catch(Exception e) {

            }
        }
    }

    public static void main(String[] args) throws Exception {

        final ObjectLevelSynchronized c = new ObjectLevelSynchronized();
        final ObjectLevelSynchronized c1 = new ObjectLevelSynchronized();       

        Thread t = new Thread(new Runnable() {
            public void run() {
                c.run();
                c.run();
            }
        }, "MyThread1");

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                c1.run();
                c1.run();
            }
        }, "MyThread2");

        t.start();
        t1.start();
    }
}

只有一个线程可以在同一监视器对象上同步的 Java 代码块内执行,我从两个不同的线程和两个不同的实例调用 run 方法。

预期结果:

MyThread1
MyThread2
MyThread1 Finished
MyThread2 Finished
MyThread1
MyThread2 
MyThread1 Finished
MyThread2 Finished

实际结果

MyThread1
MyThread1 Finished.
MyThread1
MyThread1 Finished.
MyThread2
MyThread2 Finished.
MyThread2
MyThread2 Finished.

为什么synchronized block 锁定了两个不同对象的代码?

最佳答案

你有两把不同的锁。

你使用synchronized(this)

你创建了两个对象

final ClassLevelSynchronized c = new ClassLevelSynchronized();
final ClassLevelSynchronized c1 = new ClassLevelSynchronized();     

所以,c和c1是你的锁,synchronized看起来是这些锁。您必须使用相同的对象来同步块(synchronized block)。对你来说最简单的方法是

private static Object lock = new Object();

并在同步中使用它

synchronized(lock)

或者,对于您的输出,这也应该有效。

public static void main(String[] args) throws Exception {

        final ObjectLevelSynchronized c = new ObjectLevelSynchronized();
        final ObjectLevelSynchronized c1 = new ObjectLevelSynchronized();       
        final Object lock = new Object();
        Thread t = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {
                    c.run();
                    c.run();
                }
            }
        }, "MyThread1");

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {
                    c1.run();
                    c1.run();
                }
            }
        }, "MyThread2");

        t.start();
        t1.start();
    }

关于java - 实例同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27169973/

相关文章:

java - 如何在hibernate实体中初始化复杂类型

multithreading - 等待斯卡拉的任何指定 future 吗?

java - Java 中的顺序日期和时间

java - SOAP Spring wsdl 链接

c# - SynchronizationContext.CreateCopy 的目的

c# - 为什么生成线程时会出现意外输出?

java - Java中同步关键字的使用

iOS线程安全——在线程切换前完成一段代码

java - 两个线程怎么会同时进入synchronized block 呢?

java -'javac' 在 Windows 7 中不被识别为内部或外部命令