What does synchronized()/wait()/notifyAll() do in Java?

85,095

Solution 1

This Java Tutorial can probably help you understand what using synchronized on an object does.

When object.wait() is called it will release the lock held on that object (which happens when you say synchronized(object)), and freeze the thread. The thread then waits until object.notify() or object.notifyAll() is called by a separate thread. Once one of these calls occurs, it will allow any threads that were stopped due to object.wait() to continue. This does not mean that the thread that called object.notify() or object.notifyAll() will freeze and pass control to a waiting thread, it just means these waiting threads are now able to continue, whereas before they were not.

Solution 2

The synchronized keyword is used to keep variables or methods thread-safe. If you wrap a variable in a synchronized block like so:

synchronized(myVar) {
    // Logic involing myVar
}

Then any attempts to modify the value of myVar from another thread while the logic inside the synchronized block is running will wait until the block has finished execution. It ensures that the value going into the block will be the same through the lifecycle of that block.

Solution 3

When used like this:

private synchronized void someMehtod()

You get these effects:

1. 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.

2. 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.

(Taken from here)

You get a similar effect when you use a synchronized block of code:

private void someMethod() {
  // some actions...

  synchronized(this) {
    // code here has synchronized access
  }

  // more actions...
}

As explained here

Solution 4

Java (which Android is based on) can run under multiple threads that can utilize multiple cpu cores. Multi-threading means that you can have Java doing two processes at the exact same moment. If you have a block of code or method that you need to ensure can only be operated by one thread at a time, you synchronize that block of code.

Here is the official Java explanation from Oracle

It's important to know that there is a processor/io costs involved with using synchronized and you only want to use it when you need it. It is also important to research what Java classes/methods are thread safe. For instance, the ++ increment operator is not guarateed to be thread safe, whereas you can easily create a block of synchronized code that increments a value using += 1.

Solution 5

only one thread can be active and inside block synchronized by given object. calling wait stops gives up this right and deactivates current thread until someone call notify(all)() Then the inactive thread start wanting to run in the synchronized block again, but is treated equaly with all other threads that wants it. Only one somehow chosen (programmer cannot influence nor depend on which one) actualy gets there.

Share:
85,095
Tiago Costa
Author by

Tiago Costa

My main interests are Graphics and Game Engine programming.

Updated on September 18, 2020

Comments

  • Tiago Costa
    Tiago Costa over 3 years

    Possible Duplicate:
    Java Synchronization

    I'm reading the book Beginning Android Games.

    It uses synchronized() a lot but I don't really understand what it does. I haven't used Java in a long time and I'm not sure if I ever used multithreading.

    In the Canvas examples it uses synchronized(this). However in the OpenGL ES example, it creates an Object called stateChanged and then uses synchronized(stateChanged). When the game state changes it calls stateChanged.wait() and then stateChanged.notifyAll();

    Some code:

        Object stateChanged = new Object();
    
        //The onPause() looks like this:
        public void onPause()
            {
                synchronized(stateChanged)
                {
                    if(isFinishing())
                        state = GLGameState.Finished;
                    else
                        state = GLGameState.Paused;
    
                    while(true)
                    {
                        try
                        {
                            stateChanged.wait();
                            break;
                        } catch(InterruptedException e)
                        {
                        }
                    }
                }
            }
    //The onDrawSurface looks like this:
    public void onDrawFrame(GL10 gl)
        {
            GLGameState state = null;
            synchronized(stateChanged)
            {
                state = this.state;
            }
    
            if(state == GLGameState.Running)
            {
    
            }
    
            if(state == GLGameState.Paused)
            {
                synchronized(stateChanged)
                {
                    this.state = GLGameState.Idle;
                    stateChanged.notifyAll();
                }
            }
    
            if(state == GLGameState.Finished)
            {
                synchronized(stateChanged)
                {
                    this.state = GLGameState.Idle;
                    stateChanged.notifyAll();
                }
            }
        }
    
    //the onResume() looks like this:
    synchronized(stateChanged)
            {
                state = GLGameState.Running;
                startTime = System.nanoTime();
            }