Synchronized block not working
4. The synchronized block of code will obtain a lock on the StringBuffer object from step 3.
Well, you're not doing that, are you?
synchronized(this) {
You're obtaining a lock on the instance of MySyncBlockTest
on which that run()
method is being called. That ... isn't going to do anything. There's no contention for that resource; each Thread
has its own instance of MySyncBlockTest
.
I was confused too. The answer provided by Brian is correct
synchronized (this){
is for getting the lock on an instance. It would be useful when there is a single instance of a class and multiple threads accessing it.
I wrote the following program to demonstrate this:
package com.threads.chapter9;
public class TestSunchronizedBlocksUsingRunnable implements Runnable {
StringBuffer s;
@Override
public void run() {
synchronized (this) {
for (int i = 1; i <= 100; i++) {
System.out.println(i);
}
char c = s.charAt(0);
c++;
s.setCharAt(0, c);
}
}
TestSunchronizedBlocksUsingRunnable(StringBuffer s) {
this.s = s;
}
public static void main(String[] args) {
StringBuffer s = new StringBuffer("A");
TestSunchronizedBlocksUsingRunnable instance1 = new TestSunchronizedBlocksUsingRunnable(s);
Thread thread1 = new Thread(instance1);
Thread thread2 = new Thread(instance1);
Thread thread3 = new Thread(instance1);
thread1.start();
thread2.start();
thread3.start();
}
}
The above code will display the same output but the scenario is completely different. So what you use inside synchronized block is really crucial.
You should lock on the StringBuffer object
synchronized(sb) {
for (int i=0; i<10; i++) {
System.out.print(sb);
}