【问题标题】:Calling synchronized method with two different references of the object of the same class使用同一类对象的两个不同引用调用同步方法
【发布时间】:2023-04-07 19:15:01
【问题描述】:

我有一个同步方法,我想使用同一个类的两个不同实例来调用它。我无法理解这里到底会发生什么。如果有办法强制这些调用一个接一个地执行?

Code

public class A1 {

    public synchronized void m1(){

        try{
            
            Thread.sleep(5000);

        }catch(Exception e){

        }
    }


    public static void main(String[] args) {
        A1 o1 = new A1();
        A1 o2 = new A1();
        o1.m1();
        o2.m1();
    }
}

【问题讨论】:

  • 这里只有一个线程,所以这两个调用会一个接一个地执行。你似乎对synchronized很困惑。
  • 是的,我是。实际上我刚刚开始学习这个,我正在寻找解决方法。但是谢谢你的回答。它澄清了很多事情。
  • @Sweeper 你能解释一下为什么只有一个线程吗?对不起,如果我的问题听起来很愚蠢。
  • 因为您没有在代码中创建任何新线程。你认为synchronized 会创建新线程吗?
  • 哦,是的。通过使用synchronized,我们确保线程获得了方法上的锁,并且只有在完成后才释放它。

标签: java multithreading synchronized


【解决方案1】:

synchronized 关键字将对方法锁定的访问同步到调用该方法的对象上。这意味着在同一个对象上调用该方法的两个线程将一个接一个地执行,而在两个不同对象上调用该方法的两个线程将同时执行。

如果您想在后一种情况下同步调用,您可以在两个线程都可以访问的不同对象上进行同步。这通常在 Class 对象上同步完​​成:

public class A1 {
    public void m1() {
        synchronized(A1.class) {
            try {
                Thread.sleep(5000);
            } catch(final Exception e) {
                e.printStackTrace();
            }
        }
    }
}

【讨论】:

  • 在一个类上同步是很成问题的,因为这个类不是你拥有的对象,所以系统中可能有其他组件在做同样的事情,然后你会无意中得到同步。如果你真的想在多个对象上同步,首选的解决方案是传递某种共享锁实例。
  • 你是对的,另一种方法可能是在类中创建一个static 对象并将其用作锁。无论如何,我认为在你创建的类上同步几乎没有风险。
猜你喜欢
  • 1970-01-01
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
相关资源
最近更新 更多