Synchronization block and final of Java collection instance

Asked 2 years ago, Updated 2 years ago, 24 views

Code:

public class MainClass {
  //###
  public static final List<Integer> lst = Collections.synchronizedList(new ArrayList<>());

  public static void main(String[] args) {
    for (int i = 0; i < 16; ++i) {
      lst.add(i);
    }
    System.out.println(lst);

    Runnable task = () -> {
      synchronized (lst) {
        ListIterator<Integer> itr = lst.listIterator();
        while (itr.hasNext()) {
          itr.set(itr.next() + 1);
        }
      }
    };

    ExecutorService exr = Executors.newFixedThreadPool(3);

    exr.submit(task);
    exr.submit(task);
    exr.submit(task);

    exr.shutdown();

    try {
      exr.awaitTermination(100, TimeUnit.SECONDS);
      System.out.println(lst);
    } } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

Results:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

Code that creates a thread pool with three threads and gives all three threads the same action (increase the value of each element in the collection instance by 1).

I have a question here.

Reports synchronized statements where the lock expression is a reference to a non-final field. Such statements are unlikely to have useful semantics, as different threads may be locking on different objects even when operating on the same object.

java

2022-09-21 19:19

1 Answers

In Synchronized block, if the object to be synchronized is not final, the object can be changed at runtime.

If the object is changed in the middle, the object occupying the lock in each thread will be different, allowing simultaneous access to the inside of the Synchronized block.

If you don't explicitly limit the target change by attaching the final keyword, you can cause this problem due to the developer's mistake.


2022-09-21 19:19

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.