【问题标题】:Give a C++ class foo, inside, it has a synchronized method. How to guarantee the synchronized method being accessed by only one thread给一个 C++ 类 foo,在里面,它有一个同步方法。如何保证同步方法只能被一个线程访问
【发布时间】:2011-12-16 19:39:11
【问题描述】:

给一个C++类foo,里面有一个同步方法。我们有两个 foo 的对象,被调用,f1 和 f2,如果 f1 和 f2 正在同时运行, 我们能保证同步方法只能被一个线程访问吗?

我的想法:

使用互斥锁,谁需要访问该方法,谁就获得了互斥锁。

这个面试题好像没那么简单。

有什么解决办法吗?

谢谢

【问题讨论】:

  • 我能想到的前两种方法是使用静态同步方法或使用您所说的互斥锁。
  • 您是在问如何保证一次只有一个线程访问,还是在进程的生命周期内只有一个线程访问?跨度>

标签: java c++ multithreading class synchronization


【解决方案1】:

在java中,除非方法是静态的,否则需要外部同步,以保证方法一次只被一个线程调用。

您还可以在类的静态变量上同步方法本身。例如

public class myClass
{
  private static Object myLock = new Object();

  public void myMethod()
  {
    synchronized(myLock)
    {
      // ...
    }
  }
}

【讨论】:

    【解决方案2】:

    使用静态方法,您可以在 Java 中执行以下操作:

    class Foo {
    
       public static synchronized void mymethod() {
          ...
       }
    }
    

    在这种情况下,您实际上是在 Foo.class 上同步的。

    如果您有一个实例方法(即非静态)并且您需要同步,您可以将synchronized 块放入该方法并在任何对象上同步,甚至在类本身上:

    public void mymethod() {
      synchronized( Foo.class ) {
        ...
      }
    }
    

    请注意,这会将同一类中其他静态同步方法的访问同步到共享锁对象Foo.class

    顺便说一句,这个问题的答案取决于 accessed 的定义:多个线程可以通过尝试调用该方法、读取其反射元数据甚至进入方法来访问该方法它在嵌套同步块的情况下,但它们通常不会同时执行它,除非方法的某些部分未同步(或在不同的锁对象上同步)。

    【讨论】:

    • 这仅适用于类仅由一个类加载器加载的情况。如果两个类加载器加载同一个类,两个类实例中的方法将在不同的对象上同步。然后它们可以同时执行。
    【解决方案3】:

    如果我理解正确并且您希望它在所有实例中同步,则使方法静态同步

    【讨论】:

      【解决方案4】:

      如果您有两个不同的类 foo 实例,那么发生什么并不重要,因为每个实例都有不同的方法副本,并且同步发生在 this 对象上:

      public synchronized void method() {
          // code
      }
      

      相当于:

      public void method() {
         synchronized(this) {
            // code
         }
      }
      

      话虽如此,如果每个线程从foo 的不同实例调用method

      1. 他们将获得不同的锁
      2. 如果您不修改类之外的数据,它们不会产生任何数据竞争foo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多