Why is this synchronized method not working as expected?
Can anyone please explain two questions to me why these codes don't produce the same results (the only difference between the two codes is in the run () method)?
NB: the first code doesn't seem to block!
First code:
class LetterThread extends Thread
{
private StringBuffer letter;
public static void main(String[] args) {
StringBuffer sbltr = new StringBuffer("A");
LetterThread one = new LetterThread(sbltr);
LetterThread two = new LetterThread(sbltr);
LetterThread three = new LetterThread(sbltr);
one.setName("Thread ONE");
two.setName("Thread TWO");
three.setName("Thread THREE");
one.start();
two.start();
three.start();
}
LetterThread(StringBuffer letter) {
this.letter = letter;
}
public synchronized void run() {
{
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName() + " (" + x
+ ") = " + letter);
}
letter.setCharAt(0, (char) (letter.charAt(0) + 1));
}
}
}
Second code: this code works as pending
class LetterThread extends Thread
{
private StringBuffer letter;
public static void main(String[] args) {
StringBuffer sbltr = new StringBuffer("A");
LetterThread one = new LetterThread(sbltr);
LetterThread two = new LetterThread(sbltr);
LetterThread three = new LetterThread(sbltr);
one.setName("Thread ONE");
two.setName("Thread TWO");
three.setName("Thread THREE");
one.start();
two.start();
three.start();
}
LetterThread(StringBuffer letter) {
this.letter = letter;
}
public void run() {
synchronized (letter) {
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName() + " (" + x
+ ") = " + letter);
}
letter.setCharAt(0, (char) (letter.charAt(0) + 1));
}
}
source to share
First code
The point is that you have 3 thread instances and each thread starts its own synchronized
method instance run()
. But there is always only one thread that will sync with its own method run()
, so it will run whenever the threads want to start it. This results in a lack of synchronization.
Second code
You also have 3 instances of the stream, but they have a link to the email object. Therefore, if you block this link, the threads will exclude each other and the code will work as expected.
Additional Information
This article explains a pretty good reason why the first solution doesn't work: Should the startup method be synchronized? Why or why not?
source to share