What does 'synchronized' mean?

后端 未结 17 1608
广开言路
广开言路 2020-11-22 00:13

I have some questions regarding the usage and significance of the synchronized keyword.

  • What is the significance of the synchronized
相关标签:
17条回答
  • 2020-11-22 00:36

    Synchronized normal method equivalent to Synchronized statement (use this)

    class A {
        public synchronized void methodA() {
            // all function code
        }
    
        equivalent to
    
        public void methodA() {
            synchronized(this) {
                 // all function code
            }
        } 
    }
    

    Synchronized static method equivalent to Synchronized statement (use class)

    class A {
        public static synchronized void methodA() {
            // all function code
        }
    
        equivalent to
    
        public void methodA() {
            synchronized(A.class) {
                 // all function code
            }
        } 
    }
    

    Synchronized statement (using variable)

    class A {
        private Object lock1 = new Object();
    
        public void methodA() {
            synchronized(lock1 ) {
                 // all function code
            }
        } 
    }
    

    For synchronized, we have both Synchronized Methods and Synchronized Statements. However, Synchronized Methods is similar to Synchronized Statements so we just need to understand Synchronized Statements.

    => Basically, we will have

    synchronized(object or class) { // object/class use to provides the intrinsic lock
       // code 
    }
    

    Here is 2 think that help understanding synchronized

    • Every object/class have an intrinsic lock associated with it.
    • When a thread invokes a synchronized statement, it automatically acquires the intrinsic lock for that synchronized statement's object and releases it when the method returns. As long as a thread owns an intrinsic lock, NO other thread can acquire the SAME lock => thread safe.

    => When a thread A invokes synchronized(this){// code 1} => all the block code (inside class) where have synchronized(this) and all synchronized normal method (inside class) is locked because SAME lock. It will execute after thread A unlock ("// code 1" finished).

    This behavior is similar to synchronized(a variable){// code 1} or synchronized(class).

    SAME LOCK => lock (not depend on which method? or which statements?)

    Use synchronized method or synchronized statements?

    I prefer synchronized statements because it is more extendable. Example, in future, you only need synchronized a part of method. Example, you have 2 synchronized method and it don't have any relevant to each other, however when a thread run a method, it will block the other method (it can prevent by use synchronized(a variable)).

    However, apply synchronized method is simple and the code look simple. For some class, there only 1 synchronized method, or all synchronized methods in the class in relevant to each other => we can use synchronized method to make code shorter and easy to understand

    Note

    (it not relevant to much to synchronized, it is the different between object and class or none-static and static).

    • When you use synchronized or normal method or synchronized(this) or synchronized(non-static variable) it will synchronized base on each object instance.
    • When you use synchronized or static method or synchronized(class) or synchronized(static variable) it will synchronized base on class

    Reference

    https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

    Hope it help

    0 讨论(0)
  • 2020-11-22 00:38

    The synchronized keyword causes a thread to obtain a lock when entering the method, so that only one thread can execute the method at the same time (for the given object instance, unless it is a static method).

    This is frequently called making the class thread-safe, but I would say this is a euphemism. While it is true that synchronization protects the internal state of the Vector from getting corrupted, this does not usually help the user of Vector much.

    Consider this:

     if (vector.isEmpty()){
         vector.add(data);
     }
    

    Even though the methods involved are synchronized, because they are being locked and unlocked individually, two unfortunately timed threads can create a vector with two elements.

    So in effect, you have to synchronize in your application code as well.

    Because method-level synchronization is a) expensive when you don't need it and b) insufficient when you need synchronization, there are now un-synchronized replacements (ArrayList in the case of Vector).

    More recently, the concurrency package has been released, with a number of clever utilities that take care of multi-threading issues.

    0 讨论(0)
  • 2020-11-22 00:40

    Here is an explanation from The Java Tutorials.

    Consider the following code:

    public class SynchronizedCounter {
        private int c = 0;
    
        public synchronized void increment() {
            c++;
        }
    
        public synchronized void decrement() {
            c--;
        }
    
        public synchronized int value() {
            return c;
        }
    }
    

    if count is an instance of SynchronizedCounter, then making these methods synchronized has two effects:

    • First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
    • Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
    0 讨论(0)
  • 2020-11-22 00:42

    Synchronized simply means that multiple threads if associated with single object can prevent dirty read and write if synchronized block is used on particular object. To give you more clarity , lets take an example :

    class MyRunnable implements Runnable {
        int var = 10;
        @Override
        public void run() {
            call();
        }
    
        public void call() {
            synchronized (this) {
                for (int i = 0; i < 4; i++) {
                    var++;
                    System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
                }
            }
        }
    }
    
    public class MutlipleThreadsRunnable {
        public static void main(String[] args) {
            MyRunnable runnable1 = new MyRunnable();
            MyRunnable runnable2 = new MyRunnable();
            Thread t1 = new Thread(runnable1);
            t1.setName("Thread -1");
            Thread t2 = new Thread(runnable2);
            t2.setName("Thread -2");
            Thread t3 = new Thread(runnable1);
            t3.setName("Thread -3");
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

    We've created two MyRunnable class objects , runnable1 being shared with thread 1 and thread 3 & runnable2 being shared with thread 2 only. Now when t1 and t3 starts without synchronized being used , PFB output which suggest that both threads 1 and 3 simultaneously affecting var value where for thread 2 , var has its own memory.

    Without Synchronized keyword
    
        Current Thread Thread -1 var value 11
        Current Thread Thread -2 var value 11
        Current Thread Thread -2 var value 12
        Current Thread Thread -2 var value 13
        Current Thread Thread -2 var value 14
        Current Thread Thread -1 var value 12
        Current Thread Thread -3 var value 13
        Current Thread Thread -3 var value 15
        Current Thread Thread -1 var value 14
        Current Thread Thread -1 var value 17
        Current Thread Thread -3 var value 16
        Current Thread Thread -3 var value 18
    

    Using Synchronzied, thread 3 waiting for thread 1 to complete in all scenarios. There are two locks acquired , one on runnable1 shared by thread 1 and thread 3 and another on runnable2 shared by thread 2 only.

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -1 var value 12
    Current Thread Thread -2 var value 12
    Current Thread Thread -1 var value 13
    Current Thread Thread -2 var value 13
    Current Thread Thread -1 var value 14
    Current Thread Thread -2 var value 14
    Current Thread Thread -3 var value 15
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 17
    Current Thread Thread -3 var value 18
    
    0 讨论(0)
  • 2020-11-22 00:43

    Well, I think we had enough of theoretical explanations, so consider 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() {
            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);
        }
    }
    

    Note: synchronized blocks the next thread's call to method test() as long as the previous thread's execution is not finished. Threads can access this method one at a time. Without synchronized all threads can access this method simultaneously.

    When a thread calls the synchronized method 'test' of the object (here object is an instance of 'TheDemo' class) it acquires the lock of that object, any new thread cannot call ANY synchronized method of the same object as long as previous thread which had acquired the lock does not release the lock.

    Similar thing happens when any static synchronized method of the class is called. The thread acquires the lock associated with the class(in this case any non static synchronized method of an instance of that class can be called by any thread because that object level lock is still available). Any other thread will not be able to call any static synchronized method of the class as long as the class level lock is not released by the thread which currently holds the lock.

    Output with synchronised

    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
    

    Output without synchronized

    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
    
    0 讨论(0)
提交回复
热议问题