Static and method instance synchronization

I am confused about synchronizing instance method and static method. I want to write a safe thread class as follows:

public class safe {

  private final static ConcurrentLinkedQueue<Object> objectList=
      new ConcurrentLinkedQueue<Object>();

  /**
   * retrieves the head of the object and prints it
   */
    public synchronized static  void getHeadObject() {
      System.out.println(objectList.peek().toString());

    }

    /**
     * creates a new object and stores in the list.
     */
    public synchronized void addObject() {
      Object obj=new Object();
      objectList.add(obj);

    }
}

Static synchronization blocks safe.class locks and instance synchronization blocks this. And therefore, an inconsistent state will be achieved.

If I want to achieve a consistent state for the below code snippet, how can this be achieved?

+5
source share
3 answers

Firstly, ConcurrentLinkedQueue does not require explicit synchronization. See this answer .

Secondly, you can always synchronize the object you are accessing:

public class safe {

      private final static ConcurrentLinkedQueue<Object> objectList=
          new ConcurrentLinkedQueue<Object>();

      /**
       * retrieves the head of the object and prints it
       */
     public static  void getHeadObject() {
         synchronized(objectList){
          System.out.println(objectList.peek().toString());
         }

     }

        /**
         * creates a new object and stores in the list.
         */
     public void addObject() {
          Object obj=new Object();
       synchronized(objectList){
          objectList.add(obj);
       }

     }
}
+2
source

EDIT: , Queue<Object> objectList ConcurrentLinkedQueue<Object> objectList. ConcurrentLinkedQueue<Object> , objectList.peek() , , . , , .

synchronized, , , , , synchronized :

public static void getHeadObject() {
    synchronized(safe.objectList) {
        System.out.println(objectList.peek().toString());
    }
}

objectList , . synchronized.

:

, get List.peek(), objectList, List, . , / .

, PairInt PairInt.x PairInt.y x = 2y,

System.out.println(myIntPair.x.toString() + ", " + myIntPair.y.toString());

x y ,

myIntPair.y = y + 3;
myIntPair.x = 2 * y;

, myIntPair myIntPair.x.toString() myIntPair.y.toString(), , (10, 8), , , x == 2 * y .

synchronized, , peek(), object, , , synchronized . , string, int, bool .. synchronized .

, synchronized , , java. , , , synchronized

+1

:

  • Java:
    • CamelCase (.. Safe, Safe)
    • static synchronized
    • static final
  • , ConcurrentLinkedQueue , , , .
  • , .
  • Assuming your actual use case is more complicated and you need a method to start atomic operations, then your code does not work, as you indicated, since the two synchronized methods are not synchronized on the same monitor:
public static synchronized getHeadObject(){} //monitor = Safe.class
public static synchronized addObject(){} //monitor = this

So, to answer your specific question, you can use a separate static object as a lock:

public class Safe {

    private static final ConcurrentLinkedQueue<Object> objectList =
            new ConcurrentLinkedQueue<Object>();
    // lock must be used to synchronize all the operations on objectList
    private static final Object lock = new Object();

    /**
     * retrieves the head of the object and prints it
     */
    public static void getHeadObject() {
        synchronized (lock) {
            System.out.println(objectList.peek().toString());
        }
    }

    /**
     * creates a new object and stores in the list.
     */
    public void addObject() {
        synchronized (lock) {
            Object obj = new Object();
            objectList.add(obj);
        }
    }
}
0
source

All Articles