Search code examples
javamultithreadingsynchronizationsynchronizedpool

Instance level synchronization


if I have an Object Pool class like

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++;
       }
    }

}  

And ClassA :

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

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

is some think like this will work?

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

Solution

  • Firstly let me tell you that I feel you are trying pretty hard (which is really good thing) but unfortunately your code looks like quite a mess and reading it doesn't really tell what and why you are trying to achieve, and most importantly there are many bugs like (I hope you have not shown us all code, so may look a mess, but your all actual code is all cool):

    • ClassAPool.get() promises to return ClassA but there is no return statement.
    • In Test, you are doing pool.get(); but we don't see pool being instantiated.
    • Etc...


    Now coming to answer part, I would agree with @james that information and your objective (given the code you have shown) is not very clear so answering is difficult, but I hope my below points will help you solve your problem.

    This is what you want:

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

    Your ClassAPool.get() can possibly return 10 different objects of ClassA, and then in your Test class your are trying to synchronize based on object of ClassA returned from ClassAPool.get().

    Remember, each object has only 1 lock which can be acquired and if threadA has acquired it then no other thread can acquire it until it is released by threadA. But if there are 2 different objects then 2 different threads can acquire one lock of each object. So, in your are case since ClassAPool.get() can possibly return 10 different objects of ClassA, synchronized(instance) will not help much because 10 thread can possibly acquire 10 different locks from 10 different objects of ClassA, and hence 10 threads could possibly be running doSomething() at same time.

    Yes, but if by "doSomthing() thread safe in each object" you mean that when ClassA instance=pool.get(); return the old object of ClassA and some thread is executing ClassA.doSomthing and you wish synchronization then there is some possibility that you will see some synchronization with the code you have shown (I said possibility because it depends on how many threads are requesting and each thread is using same instance of ClassAPool).

    On a side note, try using Thread.sleep in doSomthing() and print current thread id, which will give clear picture of what's going on.