A class does not need to extend Thread
or implements Runnable
to mark it's method as synchronized to protect from multiple thread access
Your class may a parameter to some other thread class and that thread class may have multiple instances. To provide strong consistency of data, you have protect your critical section of code & data.
Just change your code example as below.
I am demonstrating "synchronized
" at object level rather than class level ( static synchronized
)
class Test {
private int count = 0;
public void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
Test t = new Test();
for ( int i=0; i<10; i++){
new Thread(new MyRunnable(t)).start();
}
}
}
Your class Test
has been passed as a parameter to thread MyRunnable
. Now you have created multiple instances of threads. In absence of synchronized
keyword, the output is unpredictable as follows.
java SynchronizedDemo
Count:2
Count:3
Count:2
Count:7
Count:6
Count:5
Count:4
Count:10
Count:9
Count:8
If I change
public void incrementCount() {
to
public synchronized void incrementCount() {
the output is:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
On a different note, you have make your method as static synchronized
. That means lock is maintained at class level instead of object level.
Have a look at oracle documentation page for better understanding.
Demo of code for absence of "static synchronized
"
class Test {
private static int count = 0;
public static void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
for ( int i=0; i<10; i++){
Test t = new Test();
new Thread(new MyRunnable(t)).start();
}
}
}
output:
Count:5
Count:4
Count:3
Count:2
Count:10
Count:9
Count:8
Count:7
Count:6
After making
public static void incrementCount() {
to
ppublic static synchronized void incrementCount() {
output:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
In this example, unlike earlier, we have created 10 different Test
instances.