synchronized is a key word used for synchronization in java, and its typical scope is as follows.
1 object lock
@Slf4j public class SynchronizedExample1 { private final int loopNum = 20; // Modify a block of code private void test1(int j) { synchronized (this) { for (int i = 0; i < loopNum; i++) { log.info("test1 {} - {}", j, i); } } } // Modify a method private synchronized void test2(int num) { for (int i = 0; i < loopNum; i++) { log.info("test2 {} - {}", num, i); } } public static void main(String[] args) { SynchronizedExample1 example1 = new SynchronizedExample1(); SynchronizedExample1 example2 = new SynchronizedExample1(); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(() -> { example1.test2(1); }); executorService.execute(() -> { example2.test2(2); }); executorService.shutdown(); } }
1.1 Code Block Modification (Objects)
At this point, synchronized is used to ensure synchronized bracket-wrapped code in the test1 function is executed synchronously.
synchronized acts on object instances of synchronized Example1, such as example1 and example2 in main functions.
Tips:
1.example1 If called in multiple threads, the output sequence will be synchronized according to 1,2,3...19,20 Sequential execution.
2.if example1 and example2 If it is executed in multiple threads, test1...Keep the output synchronized. test2...Keep synchronous output between,however test1...and test2...Unguaranteed order between outputs.
1.2 Non-static Functional Modification
Synchronized is added to the test2 function declaration, and its effect is similar to the code block modification in 1.1. The difference is that its synchronized code block extends to the whole function (test2).
2. kinds of locks
@Slf4j public class SynchronizedExample2 { private static final int loopNum = 20; // Modify a class private static void test1(int j) { synchronized (SynchronizedExample2.class) { for (int i = 0; i < loopNum; i++) { log.info("test1 {} - {}", j, i); } } } // Modify a static method private static synchronized void test2(int j) { for (int i = 0; i < loopNum; i++) { log.info("test2 {} - {}", j, i); } } public static void main(String[] args) { SynchronizedExample2 example1 = new SynchronizedExample2(); SynchronizedExample2 example2 = new SynchronizedExample2(); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(() -> { example1.test1(1); }); executorService.execute(() -> { example2.test1(2); }); } }
2.1 Code Block Modification (Class)
The difference with 1.1 is that the synchronized function modifies the Synchronized Example2 class.
Synchronized Example2 objects, such as example1 or example2, call the test1 function in any number of threads, and their output order is guaranteed (1,2,3,4...19,20).
2.2 Static Function Modification
Similar to 2.1, it locks objects to ensure that multiple class objects call functions sequentially.
Tips:
In the example, because of the lock on the class, the test1 and test2 objects are executed sequentially, and there is no cross-occurrence between test1... and test2....
3 synchronized cannot be inherited
It should be noted that if synchronized is modified in functions such as 1.2 and 2.2, if a class inherits from Synchronized Example1 or Synchronized Example1, the subclass object calls test2 asynchronously.
Reason: synchronized non-functional signatures cannot be inherited, so the synchronization of subclass calls cannot be guaranteed.
PS:
If you think my article is helpful to you, you can get the red envelope by sweeping the code. Thank you.