• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

synchronized is not working. why ?

 
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Q. Here we have a CallMe class which have a call method,another class Caller implementing Runnable interface , it has a String variable.In main class three Threads have been created & initialised to different strings, now the run method creates objects of CallMe class & call method -> call which is synchronized but it is not working in a synchronized way.As the output shows.


class CallMe {
Synchronized void call(String s) {
System.out.println("["+s);
try {
Thread.sleep(1000);
}
catch(InterruptedException e) {
System.out.println(e);
}
System.out.println("]");
}
}
class Caller implements Runnable {
String str;

Caller(String s) {
str = s;
}

public void run() {
new CallMe().call(str);
}
}

class Pg240 {
public static void main(String args[]) {

CallMe cm = new CallMe();

Caller ob1 = new Caller("AMIT SETHI");
Caller ob2 = new Caller("HARISH SETHI");
Caller ob3 = new Caller("HEMANT SETHI");

Thread t1 = new Thread(ob1);
Thread t2 = new Thread(ob2);
Thread t3 = new Thread(ob3);

t1.start();
t2.start();
t3.start();

try {
t1.join();
t2.join();
t3.join();
}
catch(InterruptedException e) {
System.out.println("main interrupted");
}
}
}



output :without synchronised:

F:\j5se\cr>javac Pg240.java

F:\j5se\cr>java Pg240
[AMIT SETHI
[HARISH SETHI
[HEMANT SETHI
]
]
]


output :with synchronised: (both are same why ?)

F:\j5se\cr>javac Pg240.java

F:\j5se\cr>java Pg240
[AMIT SETHI
[HARISH SETHI
[HEMANT SETHI
]
]
]

pls help me .
Thanks in advance.
regards
Amit Sethi
 
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What do you expect to happen? You have three different threads using three different CallMe instances. Synchronization doesn't even enter into the picture, you do not have in any place more than one method executing the same code on the same instance.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you misunderstand how synchronization works in Java.

Synchronization works with locks. Inside a synchronized method or block, the lock of the object you are synchronizing on is locked. You can only enter a synchronized method or block if the lock is unlocked (which means that no other thread is executing the method or block using the same object).

Note, the "using the same object" is important to understand here.

You have three different Caller objects. Each of those has its own lock. If you lock the lock of ob1, the locks of ob2 and ob3 are still unlocked, and you can still call the call() method on ob2 and ob3 without having to wait for the lock.

Try changing your code like this and you'll see that it will work:
 
Amit Sethi
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Fst of all thanks gyus , I understood the concept now.

Q. But how this code working fine ? (code from complete refrence j2se 5 edition Page no.239.


class Callme {
synchronized void call(String msg) {
System.out.println("["+msg);
try {
Thread.sleep(1000);
}
catch(InterruptedException e) {
System.out.println(e);
}
System.out.println("]");
}
}

class Caller implements Runnable {
String msg;
Thread t;
Callme target;

public Caller(Callme trag,String s) {
target = trag;
msg = s;
t = new Thread(this);
t.start();
}

public void run() {
target.call(msg);
}
}

class Pg239_2 {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target,"hello");
Caller ob2 = new Caller(target,"synchronized");
Caller ob3 = new Caller(target,"world");

try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
}
catch(InterruptedException e) {
System.out.println(e);
}
System.out.println("main exit now");
}


output:
F:\j5se\cr>javac Pg239_2.java

F:\j5se\cr>java Pg239_2
[hello
]
[synchronized
]
[world
]
main exit now


pls help me.
regards
Amit Sethi
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
All of the "Caller" instances are using the same "Callme" instance. As such one "Caller" cannot execute call(String) on the Callme instance until it acquires the monitor for that instance. So the first thread to execute call(msg) acquires the monitor, executes the code, then leaves the call() method and releases the monitor. At this point the remaining to threads which have been blocked and waiting on that monitor compete to acquire it. One of them does and it then executes the call() method. Once it finishes it releases the monitor and that allows the third and final thread, which is still waiting, to acquire the monitor and complete call() itself. Basically, only one thread can execute call() on any given Callme instance at a time. That's any given instance, since they're all executing on the same instance that means only one of them can execute it at a time. In your case you had three different instances of Callme so they did not conflict.
 
reply
    Bookmark Topic Watch Topic
  • New Topic