-1

There might be a straightforward for this issue, but I am not understanding the concept here.

I am trying a simple program where I am having 3 threads executing a synchronized block to print letter in an incrementing order.The synchronized block is having lock on the variable(which is a StringBuffer object). Below is the code:

public class SimpleThread extends Thread implements Runnable{

    private StringBuffer myBuffer;

    public StringBuffer getMyBuffer() {
        return myBuffer;
    }

    public void setMyBuffer(StringBuffer myBuffer) {
        this.myBuffer = myBuffer;
    }

    public SimpleThread(StringBuffer myBuffer) {
        this.myBuffer = myBuffer;
    }

    public void run() {
        synchronized (this.myBuffer) {
            while((int)(this.myBuffer.charAt(0))!=68) {
                for(int i=0;i<3;i++) {
                    System.out.println(this.myBuffer.charAt(0));
                }
                char x = this.myBuffer.charAt(0);
                this.myBuffer.setCharAt(0, (char) (x+1));
            }
            //this.myBuffer.setCharAt(0, 'A');
        }
    }

    public static void main(String[] args) {
        StringBuffer safeBuffer = new StringBuffer();
        safeBuffer.append('A');
        SimpleThread one = new SimpleThread(safeBuffer);
        one.setName("One");
        one.start();

        SimpleThread two = new SimpleThread(safeBuffer);
        two.setName("Two");
        two.start();

        SimpleThread three = new SimpleThread(safeBuffer);
        three.setName("Three");
        three.start();
    }

Output for the program is:

A
A
A
B
B
B
C
C
C

It is only printing the value when thread One is executing and for other two threads, the of variable myBuffer is becoming D. What I don't understand is why changing the variable for one object reflect for other objects?

PM 77-1
  • 12,933
  • 21
  • 68
  • 111
Abhinash Jha
  • 165
  • 1
  • 3
  • 17
  • Unclear what you're expecting to happen, and why. There is only one shared buffer. How else could it execute? – user207421 Feb 06 '20 at 00:18

1 Answers1

1

synchronized means only one thread can execute the code block at a time. You might be confusing the wording to think it synchronizes the variable.

When you write synchronized (this.myBuffer), you are telling the program to use myBuffer as a lock when deciding if a thread can execute the following code block.

This means when a thread tries to execute synchronized (this.myBuffer) { } it will attempt to get the lock on myBuffer.

  • If no other thread has the lock, it will obtain it and execute the code block.
  • If another thread has the lock it will wait until the other thread releases the lock (usually by finishing running the code inside the code block).

That means all threads will always take turns executing the contents of synchronized (this.myBuffer) { }.

Since thread "One" is started first, it will get the lock first and finish all the work it has thus incrementing the myBuffer content to D, before handing it over to thread "Two".

  • Thanks for the explanation. But, this.myBuffer would mean the value of myBuffer of the objext executing it. So, as we have initialized three different objects and so they should have their own copy for myBuffer. Now, when "two" gets its turn, at that point how the value of its myBuffer should be 'A', as the value of its copy is not yet updated.Am I able to explain? – Abhinash Jha Feb 06 '20 at 01:03
  • Everything in java is passed by value, how ever when we pass the value of an object, the value is a reference to the object. You're passing a reference of the same object to all 3 threads. Learn more about this here: https://stackoverflow.com/a/40523/4425643 – CausingUnderflowsEverywhere Feb 06 '20 at 01:55
  • You probably see that when you pass something to a method, the method makes a copy. Yes, but it makes a copy of the reference when it's an Object. If you pass a primitive how ever such as an int, then the value is the number itself. Any type with a capital letter as the first is a subclass of Object. Even Strings, they are just immutable and behave like primitives. – CausingUnderflowsEverywhere Feb 06 '20 at 01:59
  • Yes, but it makes a copy of the reference when it's an Object-- this is the point that makes it clear. Thanks for the explanation. – Abhinash Jha Feb 06 '20 at 17:19