java - 实例级同步

标签 java multithreading synchronization synchronized pool

如果我有一个像这样的对象池类

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()
   {
      .....
   }
}

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

有人认为这样行得通吗?

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

最佳答案

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

  • ClassAPool.get() promise 返回 ClassA,但没有 return 语句。
  • 测试中,您正在执行pool.get();,但我们没有看到pool被实例化。
  • 等等...


现在开始回答部分,我同意@james的观点,即信息和您的目标(考虑到您所显示的代码)不是很清楚,因此回答很困难,但我希望我的以下几点将帮助您解决您的问题。

这就是你想要的:

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

您的 ClassAPool.get() 可能会返回 10 个不同的 ClassA 对象,然后在您的 Test 类中尝试同步基于从 ClassAPool.get() 返回的 ClassA 对象。

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

是的,但是如果“doSomthing() 在每个对象中都是线程安全的”,则意味着当 ClassA instance=pool.get(); 返回旧对象时ClassA 并且某个线程正在执行 ClassA.doSomthing 并且您希望同步,那么您有可能会看到与您所显示的代码的一些同步(我说可能性,因为这取决于有多少线程正在请求,并且每个线程都使用相同的 ClassAPool 实例。

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

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

相关文章:

java - 是否可以使用在其父类(这是内部类)中实现的类?

java - Thread类和Object类中的方法

java - 有人能告诉我如何在 java 中创建线程组中 n 个线程的数组吗?

go - 跨多个 goroutine 使用单个互斥锁

java - 如何在多线程中使用等待和通知协议(protocol)

java - 如何在java中将不同货币的货币表示形式转换为十进制值

java - 如何调用签名为 "public double getMedian(double[]list) {//code}"的方法

JavaFX 和套接字 = 不在 FX 应用程序线程上

java - AgitarOne无法连接到本地主机:8080/agitar-server on eclipse

python - threading.Condition.wait() 未捕获 SIGTERM