0

I am trying to run a simple multi-threaded program in java that uses a synchronized block inside a non-static method.I have a class TestThread which has a field string which is a StringBuffer variable. I have created two threads one and two and each of their string variables initialized to StringBuffer b which contains the value A . The first thread that goes to running state has to display the value A hundred times and after that increment it by one so that the next thread running will display the incremented value B hundred times too.I have used the current object denoted by this inside the synchronized. But unfortunately I am not getting the expected output. The first thread is displaying A more than hundred times and second thread is displaying B less than 100. And each time I run it, I am getting different outputs.So I think that the mutual exclusion is not achieved. What I am doing wrong here?

 public class TestThread extends Thread{ StringBuffer string; public void run(){ synchronized(this){ for(int i=0;i<100;i++){ System.out.print(this); } System.out.println(); string.setCharAt(0,(char)(string.charAt(0)+1)); } } public TestThread(StringBuffer string){ this.string=string; } public String toString(){ return string.toString(); } public static void main(String args[]){ StringBuffer b=new StringBuffer("A"); TestThread one=new TestThread(b); TestThread two=new TestThread(b); one.start(); two.start(); } } 
12
  • 1
    Please don't use StringBuffer as it was replaced by StringBuilder more than 10 years ago. Commented Aug 26, 2015 at 9:56
  • Also don't extend Thread unless you like really obscure bugs to appear in your code. You should implement Runnable and pass this to a new Thread Commented Aug 26, 2015 at 9:57
  • 1
    When you use synchronized the choice of object to lock on matters, you need to lock on the same object as the other thread, the obvious choice being the object you want to modify e.g. the String Commented Aug 26, 2015 at 9:58
  • 2
    @hermit - this is different for different threads. Got it? Commented Aug 26, 2015 at 10:01
  • 1
    Never the less using StringBuffer is a bad idea, too many people think it's thread safe when it is almost impossible to use it correctly that way. Commented Aug 26, 2015 at 10:02

1 Answer 1

2

You are locking on the current object i.e, this. Thus you are locking on 2 different objects. Use a common lock and then try the same example.

synchronized(this) ==> synchronized(someGlobalObject)

Sign up to request clarification or add additional context in comments.

5 Comments

... like the global object the thread is modifying ie string
@PeterLawrey - I would prefer a different one.. Perhaps an Object.. But you are right.. :)
but when i checked the class 'this' belonged to , for all the threads it was TestThread class. But it works if i use 'string'.
@hermit - the lock is on a specific instance of a class, not on the whole class. this is the current instance of TestThread - either the instance you created in one or the one you placed in two.
@RealSkeptic o I got it.Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.