Saturday, December 26, 2015

Thread and Synchronization


How does synchronization work?

With locks. Every object in Java has a built-in lock that only comes into play when the object has synchronized method code.
When we enter a synchronized non-static method, we automatically acquire the lock associated with the current instance of the class whose code we're executing (the this instance). Acquiring a lock for an object is also known as getting the lock, or locking the object, locking on the object, or synchronizing on the object.
Since there is only one lock per object, if one thread has picked up the lock, no other thread can pick up the lock until the first thread releases (or returns) the lock.
This means no other thread can enter the synchronized code (which means it can't enter any synchronized method of that object) until the lock has been released.

package com.test;

public class SynchronizedThread {

private int count;

public static void main(String[] args) throws InterruptedException {
SynchronizedThread st = new SynchronizedThread();
st.doWork();
}

public synchronized void increment(){
count++;
}

public void doWork() throws InterruptedException {

Thread t1 = new Thread(new Runnable() {
public void run() {
for(int i=1;i<=10000;i++)
increment();
}

});
Thread t2 = new Thread(new Runnable() {
public void run() {
for(int i=1;i<=10000;i++)
increment();
}

});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Count is "+ count);
}
}

Output:
Without using Synchronized keyword, it gives any random value 14299 or anything…
By giving Synchronized keyword, Thread t1 gets the lock on the object and Thread t2 ,since using same object has to wait till Thread t1 preempt the lock i.e. exit from method. At one time, only 1 thread can access the method.
Key points about locking and Synchronization:

 Only methods (or blocks) can be synchronized, not variables or classes.

 Each object has just one lock.

 Not all methods in a class need to be synchronized. A class can have both
synchronized and non-synchronized methods.

 If two threads are about to execute a synchronized method in a class, and
both threads are using the same instance of the class to invoke the method,
only one thread at a time will be able to execute the method. The other
thread will need to wait until the first one finishes its method call. In other
words, once a thread acquires the lock on an object, no other thread can
enter any of the synchronized methods in that class (for that object).

 If a class has both synchronized and non-synchronized methods, multiple
threads can still access the class's non-synchronized methods! If you have
methods that don't access the data you're trying to protect, then you don't
need to synchronize them. Synchronization can cause a hit in some cases (or
even deadlock if used incorrectly), so you should be careful not to overuse it.

 If a thread goes to sleep, it holds any locks it has—it doesn't release them.

 A thread can acquire more than one lock. For example, a thread can enter a
synchronized method, thus acquiring a lock, and then immediately invoke
a synchronized method on a different object, thus acquiring that lock as
well. As the stack unwinds, locks are released again. Also, if a thread acquires
a lock and then attempts to call a synchronized method on that same
object, no problem. The JVM knows that this thread already has the lock for
this object, so the thread is free to call other synchronized methods on the
same object, using the lock the thread already has.

 You can synchronize a block of code rather than a method.
Java Synchronization works only in the same JVM, so if you need to lock some resource in multiple JVM environment, it will not work and you might have to look after some global locking mechanism.

References :
https://stackoverflow.com/questions/1085709/what-does-synchronized-mean/44443323#44443323

No comments:

Post a Comment