Reputation: 5628
You can copy paste the below example to run on your local machine. I am learning MultiThreading and I came across this example online. I am confused as to why the method add(inside class Counter) would make a difference if declared synchronized, you can remove the keyword synchronized from it and it would not affect the end result so I am just wondering what's the purpose to be served by declaring it synchronized
class Counter {
long count = 0;
public synchronized void add(long value) {
this.count += value;
System.out.println(count + "-" + Thread.currentThread().getName());
}
}
class CounterThread extends Thread {
protected Counter counter = null;
public CounterThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(CounterThread.class.getName()).log(Level.SEVERE, null, ex);
}
counter.add(i);
}
}
}
public class Example {
public static void main(String[] args) {
Counter counter = new Counter();
Thread threadA = new CounterThread(counter);
Thread threadB = new CounterThread(counter);
Thread threadC = new CounterThread(counter);
threadA.start();
threadB.start();
threadC.start();
}
}
Upvotes: 2
Views: 67
Reputation: 12527
Declaring the class as synchronized
means that whatever thread wants to execute the method must first acquire the current object's lock. The object has exactly one lock and only the thread that has obtained it can execute the method. Other threads must wait until the lock-holding thread is done. Upon completion of the method, the executing thread releases the lock.
In short. the synchronized
keyword ensures that at any given time, only one thread can execute the method.
Synchronization is important on classes where (a) the system is multi-threaded; (b) The class has instance variables that can be changed within the method. Multi-threading issues typically occur when two or more threads are executing the same method simultaneously. One thread can change an instance variable based on its inputs, and those changes are seen by the other thread.
In this particular example, a problem could arise with the instance variable count
. If one thread sets it to say 5, a second thread could come along and set it to 10. When the first thread then executes the System.out.println call, it prints a value of 10 - which is unexpected behavior.
Upvotes: 4
Reputation: 424973
The reason that making the add()
method synchronised is important is that this line:
this.count += value;
Is not an atomic action. It a really compiles as this (or similar):
long c = count;
c = c + value;
count = c;
Which should be pretty obviously not threadsafe.
Upvotes: 3
Reputation: 33936
The synchronized
keyword prevents threadA, threadB, and threadC from executing the operations at the same time. It's important to understand that this.count += value
is internally implement as three operations:
If you remove the synchronized
keyword, then you can imagine the following sequence of events:
Upvotes: 4