开发者

How does the synchronize functionality work in java?

开发者 https://www.devze.com 2023-03-17 04:46 出处:网络
Since开发者_运维问答 I\'ve started programming in Java I have been wondering this (about a year or two). In C, we must know the different method to correctly avoid deadlock between thread and thus the

Since开发者_运维问答 I've started programming in Java I have been wondering this (about a year or two). In C, we must know the different method to correctly avoid deadlock between thread and thus there is much more choice between synchronization method.

So what about Java? When we synchronize, how does it avoid putting thread in deadlock situation? How does it work internally? Does the deadlock are avoided because we synchronized on higher level than in C ( or C++)? Any documentation about deadlock and synchronization in java?


Under the hood it is using two opcodes monitorenter and monitorexit at the byte code level which acquire/release locks on an object reference at a JVM global level. I highly recommend you read How the Java virtual machine performs thread synchronization.


The main problem(s) we meet with a multithreaded code is sharing data, and I agree with, the purpose of concurency parallizing process and it happens "ofently" that during parallalized processing that threads need accessing for read/write on shared data.

The java synchronized keyword permits the following:

It tells the JVM to put a lock on the monitor of the object or the piece of the synchronized code, which gives it exclusive access to that part of code or object.

Here's an example of a Singleton:

public class Singleton {
    private Singleton INSTANCE;

    private Singleton() {
    }

    public Singleton getInstance() {
        if (null == INSTANCE) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

This Singleton is not thread safe, if a thread is trying to get an instance while another is also trying to do the same (race condition) it may happen that before that the thread number one finishes the creation of the instance the second has already had access to the getInstance() method and created his own instance of the Singleton which means that at a T time we should have two instances of the Singleton (called multiton at that time).

To solve this problem we have to synchronize the creational behaviour of the singleton, this may be done by the keyword synchronized above the if statement on the INSTANCE itself:

public class Singleton {
    private Singleton INSTANCE;

    private Singleton() {
    }

    public Singleton getInstance() {
        synchronized (Singleton.class) {
            if (null == INSTANCE) {
                synchronized(Singleton.class) {
                   Singleton inst = new Singleton();
                   INSTANCE = inst;   
                }
            }
        }
        return INSTANCE;
    }
}

The result is when the first thread asks the Singleton instance and during creation time, the JVM will put a lock on the monitor of the INSTANCE denying any access to the INSTANCE until thread one finished its request.

There are diffrent ways to achieve that as well, the book cited before is an excellent source of learning, javadoc also.


Synchronization isn't really that much easier in Java than in C. Syntactically it's easier, because all you need to do for a mutex is declare a method as synchronized or use

synchronized(someObject)
{
   someCode();
}

Whereas in C/C++, you have to use operating-system-specific functions to use a mutex, or you have to use the Boost library.

But the pitfalls about deadlock are all basically the same as in any language.


Short answers:

  1. synchronized methods and lock blocks use a monitor that locks the semaphore of the locked object for the duration of the method or block.

  2. The Java language itself does not prevent deadlocks. That's up to you as the programmer to insure that objects are locked/unlocked in the correct order to prevent contention.


You also have to take care of deadlocks in Java. The easiest way to get a deadlock is to make one thread run a block synchronized on A, and then another block synchronized on B, while another thread executes a block synchronized on B, and then a block synchronized on A.

Read the Java tutorial about concurrency. And if you want to keep learning, read Java concurrency in practice.


Did you try google (Java Deadlock)? First result is this: http://download.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

There you can see that with synchronized deadlocks still occur, since synchronization is not designed to prevent those in the first place.


I see some issue with Singleton above. I think that class will never be created. Please consider below code.

public class Singleton {
     private static Singleton INSTANCE;
     private Singleton() {     }
     public static Singleton getInstance() {
         synchronized (Singleton.class) {
             if (null == INSTANCE) {
                 synchronized(Singleton.class) {
                    Singleton inst = new Singleton();
                    INSTANCE = inst;
                    }
             }
         }
         return INSTANCE;
     }
 } 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号