Summary
synchronized is a very important keyword in java. It is mainly used to control the synchronization of threads. It can realize the exclusive access of critical area resources in multithreaded environment.
The synchronized keyword is mainly used in the following three ways, which are described below
- Modify the instance method to lock the current instance, and obtain the lock of the current instance before entering the synchronization code.
- Modify the static method to lock the current class object, and obtain the lock of the current class object before entering the synchronization code.
- Decorate the code block, specify the lock object, lock the given object, and obtain the lock of the given object before entering the synchronization code base.
- Decorate the code block. If the lock object is an object, all objects of the class share the same lock.
1. Modify instance method
class SafeAdd implements Runnable { public static int num = 0; public synchronized void add() { num ++; } @Override public void run() { for (int i = 0; i < 10000; ++i) { add(); } } } public class SyncMethod { public static void main(String[] args) throws InterruptedException { SafeAdd safeAdd = new SafeAdd(); Thread t1 = new Thread(safeAdd); Thread t2 = new Thread(safeAdd); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("SafeAdd: num = " + SafeAdd.num); } }
Operation result:
SafeAdd: num = 20000 Process finished with exit code 0
2. Modify static method
class SafeAdd implements Runnable { public static int num = 0; public static synchronized void add() { num ++; } @Override public void run() { for (int i = 0; i < 10000; ++i) { add(); } } } public class SyncMethod { public static void main(String[] args) throws InterruptedException { SafeAdd safeAdd1 = new SafeAdd(); SafeAdd safeAdd2 = new SafeAdd(); Thread t1 = new Thread(safeAdd1); Thread t2 = new Thread(safeAdd2); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("SafeAdd: num = " + SafeAdd.num); } }
Operation result:
SafeAdd: num = 20000 Process finished with exit code 0
3. Synchronization code block
class SafeAdd implements Runnable { public static int num = 0; @Override public void run() { synchronized (this) { for (int i = 0; i < 10000; ++i) { num ++; } } } } public class SyncMethod { public static void main(String[] args) throws InterruptedException { SafeAdd safeAdd = new SafeAdd(); Thread t1 = new Thread(safeAdd); Thread t2 = new Thread(safeAdd); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("SafeAdd: num = " + SafeAdd.num); } }
Operation result:
SafeAdd: num = 20000 Process finished with exit code 0
4. Synchronize code block, lock object is Class object
class SafeAdd implements Runnable { public static int num = 0; public static void add() { num ++; } @Override public void run() { synchronized (SafeAdd.class) { for (int i = 0; i < 10000; ++i) { add(); } } } } public class SyncMethod { public static void main(String[] args) throws InterruptedException { SafeAdd safeAdd1 = new SafeAdd(); SafeAdd safeAdd2 = new SafeAdd(); Thread t1 = new Thread(safeAdd1); Thread t2 = new Thread(safeAdd2); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("SafeAdd: num = " + SafeAdd.num); } }
Operation result:
SafeAdd: num = 20000 Process finished with exit code 0
summary
- When the role object of synchronized is instance method and common object, multiple threads only compete for the lock of the object.
- When a synchronized action object is a static method or a class, all objects of that class share a lock.