1. Preface
Have you ever wondered if the ++ operation in Java is thread-safe, that is, if multiple threads execute the ++ operation together in a multi-threaded situation, the result will not be what we expected. You can write a demo to verify it.
public static int count = 0; public static void main(String[] args) { for (int j = 0; j < 10000; j++) { new Thread(new Runnable() { @Override public void run() { add(); } }).start(); } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); } public static void add(){ count++; }
The final execution results are as follows:
Clearly, the ++ operations in Java are not thread-safe.
This involves how thread security can be guaranteed when operating on the same variable or method in a multithreaded environment.
2. Synchronized
What is Synchronized?
Synchronized keyword is the use of a specific object to set a lock that allows only one thread to acquire and execute code when multithreaded concurrent access occurs, until the code is executed, the lock is released, and then competition continues with other threads.
Use of Synchronized
We can slightly alter the demo above to make ++ operations thread safe.
public static int count = 0; public static void main(String[] args) { for (int j = 0; j < 10000; j++) { new Thread(new Runnable() { @Override public void run() { add(); } }).start(); } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); } public synchronized static void add(){ count++; }
Just make a small change by adding the synchronized keyword to the add() method to see the results:
Multiple executions yielded 10,000 results, which was expected, and the **add()** method became a thread-safe method.
Scenarios for using Synchronized
Synchronized has three different usage scenarios and corresponds to different lock objects.
1.Synchronized Code Block
Modify the **add()** method of the demo above
public static void add(){ Object o = new Object(); //Lock Object synchronized (o){ count++; } }
Define an Object object and use Object as the lock object. Only one thread will get the lock object and perform the ++ operation. When other threads need to wait for the lock object to be released, compete for the lock object so that the lock object can be acquired to proceed with the ++.
2.Synchronized method
public synchronized void add(){ ... ... }
What is the lock object for this add() method? Clearly, this is the current object, and the thread gets the current object.
3.Synchronized static methods
public synchronized static void add(){ count++; }
The last one is the **add()** method in demo, in which case the lock object is the byte code object of the current class, because the static method belongs to this class, so the lock object is the byte code object of the current class.
summary
Synchronized Using in the code block, the lock object can be any object. Synchronized In the method, the lock object is the current object this. Synchronized Using the static method, the lock object is the byte code object of the current class.
3. Common use of Synchronized classes
Vector is thread-safe, ArrayList, LinkedList is thread-insecure
Properties are thread-safe, HashSet, TreeSet are not
StringBuffer is thread-safe, StringBuilder is thread-insecure
HashTable is thread-safe, HashMap is thread-insecure
4. Summary
Synchronized can ensure data security for multithreaded data sharing, but if used improperly, threads hold lock objects for a long time and are not released in time, which can easily cause deadlock problems.
Also, Synchronized has a certain impact on performance, so be careful with Synchronized.
Thank you for watching. If it is helpful, please give us a pat on the back. Thank you.