I have some questions regarding the usage and significance of the synchronized keyword.
synchronized
In java to prevent multiple threads manipulating a shared variable we use synchronized keyword. Lets understand it with help of the following example:
In the example I have defined two threads and named them increment and decrement. Increment thread increases the value of shared variable (counter) by the same amount the decrement thread decreases it i.e 5000 times it is increased (which result in 5000 + 0 = 5000) and 5000 times we decrease (which result in 5000 - 5000 = 0).
Program without synchronized keyword:
class SynchronizationDemo {
public static void main(String[] args){
Buffer buffer = new Buffer();
MyThread incThread = new MyThread(buffer, "increment");
MyThread decThread = new MyThread(buffer, "decrement");
incThread.start();
decThread.start();
try {
incThread.join();
decThread.join();
}catch(InterruptedException e){ }
System.out.println("Final counter: "+buffer.getCounter());
}
}
class Buffer {
private int counter = 0;
public void inc() { counter++; }
public void dec() { counter--; }
public int getCounter() { return counter; }
}
class MyThread extends Thread {
private String name;
private Buffer buffer;
public MyThread (Buffer aBuffer, String aName) {
buffer = aBuffer;
name = aName;
}
public void run(){
for (int i = 0; i <= 5000; i++){
if (name.equals("increment"))
buffer.inc();
else
buffer.dec();
}
}
}
If we run the above program we expect value of buffer to be same since incrementing and decrementing the buffer by same amount would result in initial value we started with right ?. Lets see the output:
As you can see no matter how many times we run the program we get a different result reason being each thread manipulated the counter at the same time. If we could manage to let the one thread to first increment the shared variable and then second to decrement it or vice versa we will then get the right result that is exactly what can be done with synchronized keyword by just adding synchronized keyword before the inc and dec methods of Buffer like this:
Program with synchronized keyword:
// rest of the code
class Buffer {
private int counter = 0;
// added synchronized keyword to let only one thread
// be it inc or dec thread to manipulate data at a time
public synchronized void inc() { counter++; }
public synchronized void dec() { counter--; }
public int getCounter() { return counter; }
}
// rest of the code
and the output:
no matter how many times we run it we get the same output as 0