实例级同步

Instance level synchronization

如果我有一个像

这样的对象池 class
public class ClassAPool 
{
    private final ClassA[] objects=new ClassA[10]
    private int current=0;
    public synchronized ClassA get()
    {
       ClassA instance;
       if(objects[current]==null)
       {
          objects[current]=new ClassA()
       }
       instance=objects[current];
       if(current==objects.length-1)
       {
          current=0;
       }else{
          current++;
       }
    }

}  

A 类:

public class ClassA{
   public void doSomething()
   {
      .....
   }
}

而且我想在另一个 class 中使用 Pool 并使每个对象中的方法 doSomthing() 线程安全。

有人认为这样可行吗?

public class Test{
  ClassAPool pool;
  public void testMethod()
  {  
     ClassA instance=pool.get();
     synchronized(instance)
     {
       instance.doSomething();
     }
  }
}

池与你的问题无关。据我所知,你的问题是关于 instance.doSomething() 调用是否是线程安全的。

这里没有足够的信息来回答这个问题,因为答案取决于 data instance.doSomething() 可能操作的内容。

如果它仅在 instance 的字段上运行,那么您向我们展示的一个调用可能是 "thread-safe",但您没有告诉我们这是唯一的 doSomething() 调用.如果在您的代码中的其他地方有另一个 doSomething() 调用,那么该调用可能 不是 线程安全的。

同样,如果有两个不同的实例,其 doSomething() 方法可能对相同的共享数据进行操作,即使您向我们展示的一个调用也不是线程安全的。

首先让我告诉你,我觉得你很努力(这真的很好)但不幸的是你的代码看起来很乱而且阅读它并没有真正说明您要实现什么以及为什么要实现,最重要的是有很多错误,例如(我希望您没有向我们展示所有代码,所以看起来可能一团糟,但您所有的实际代码都很酷):

  • ClassAPool.get() 承诺 return ClassA 但没有 return 声明。
  • Test 中,您正在执行 pool.get(); 但我们没有看到 pool 被实例化。
  • 等等...


现在来回答部分,我同意@james 的信息和你的objective(给定你显示的代码)不是很清楚所以回答很难,但我希望我的以下几点可以帮助您解决问题。

这就是你想要的:

And I want to use the Pool in another class and make method doSomthing() thread safe in each object.

您的 ClassAPool.get() 可能 return ClassA 的 10 个不同对象,然后在您的 Test class 中您正尝试基于对象进行同步ClassA return 编辑自 ClassAPool.get().

记住,每个对象只有 1 个可以获取的锁,如果线程 A 获取了它,那么在它被线程 A 释放之前,其他线程无法获取它。但是如果有是 2 个不同的对象,那么 2 个不同的线程可以获得每个对象的一个​​锁。所以,在你的情况下,因为 ClassAPool.get() 可能 return ClassA 的 10 个不同的对象,synchronized(instance) 不会有太大帮助,因为 10 个线程可能从 10 个不同的对象获取 10 个不同的锁ClassA 的对象,因此 10 个线程可能同时是 运行 doSomething()

是的,但是如果通过“doSomthing() 在每个对象中线程安全”你的意思是当 ClassA instance=pool.get(); return [= 的旧对象11=] 并且某些线程正在执行 ClassA.doSomthing 并且您希望同步,那么您可能会看到与您显示的代码同步( 我说可能性是因为它取决于有多少线程正在请求并且每个线程都使用 ClassAPool).

的相同实例

附带说明一下,尝试在 doSomthing() 中使用 Thread.sleep 并打印当前线程 ID,这将清楚地显示正在发生的事情。