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));
        }
    }

      

+3


source to share


2 answers


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?

+1


source


If you want to synchronize two threads, you must block the shared resource by all threads. When synchronizing in the run method (or any instance method in the thread class), each thread blocks its own method, resulting in no synchronization.



0


source







All Articles