How to understand synchronized |The Java Debug notes

This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

Ask questions

How to understand the synchronized keyword?

Specifically, I have the following questions about the use and importance of synchronized:

What is the meaning of the keyword synchronized? When should synchronized be used before a method? What does synchronized mean programmatically and logically?

Top Answers

Answer 1:

The synchronized keyword is used when different threads need to read and write the same variables, objects, and resources. This is an important topic in Java, and here’s Sun’s quote:

Synchronized methods that use the synchronized keyword provide a simple strategy to prevent thread interference and memory consistency errors: If an object is visible to more than one thread, all reads or writes to that object’s variables are done through the synchronized method.

In short: When two threads are reading and writing to the same “resource,” say, a variable named foo, you need to make sure those threads have atomic access to the variable. Without the synchronized keyword, your thread 1 might not see the changes that thread 2 made to Foo, or worse, it might only have changed half as much. This is not logically what you would expect.

Again, this is a very important topic in Java. For more information, explore the following topics at SO and Interwebs:

  • concurrent
  • Java memory model

Continue exploring these themes until master Brian Goetz’s name becomes permanently associated with the word “concurrency” in the brain.

Brian Goetz is the Java Language architect at Oracle and the director of the JSR-335 (Lambda Expressions for the Java Language) specification. He is the author of the bestselling Java Concurrent Programming In Action, and is a frequent attendee of various industry conferences.

Answer 2:

Well, I think we have enough theory to explain it, so take a look at this code:

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n"); }}public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run(a) { theDemo.test(name); }}public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0; i<10; i++) { SOP.print(name +"... ""+i);
            try{
                Thread.sleep(500);
            } catch(Exception e) { SOP.print(e.getMessage()); }}}public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo); }}Copy the code

Note: Synchronized blocks calls to the test() method from the next thread as long as the previous thread’s execution is incomplete. Threads can access this method once. If the test method does not add the synchronized keyword, all threads can access the method at the same time.

When a thread calls the synchronized method test() of an object (where the object is an instance of the TheDemo class), it obtains the lock of that object. No new thread can call any synchronized method of the same object, as long as the previous thread that acquired the lock does not release the lock.

A similar situation occurs when any of the statically synchronized methods of the class are called. The thread acquirement the lock associated with the class (in this case, any class can call any non-statically synchronized method of an instance of the class, since the object-level lock is still available). As long as the thread currently holding the lock does not release the lock at the class level, no other thread will be able to call any of the statically synchronized methods of the class.

Output:

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9
Copy the code

Output from the test() method with synchronized removed:

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
Copy the code

Answer 3:

The synchronized keyword prevents multiple threads from accessing code or object blocks simultaneously. All methods of a Hashtable are synchronous, so only one thread can execute any one of them at a time.

When using asynchronous structures (such as HashMap), thread-safety features must be built into the code to prevent consistency errors.

The original link