This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes 2 thread instances using the same Runnable object Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "2 thread instances using the same Runnable object" Watch "2 thread instances using the same Runnable object" New topic
Author

2 thread instances using the same Runnable object

Justyna Wozniak
Greenhorn

Joined: Oct 04, 2006
Posts: 14
Hello,
I am wondering why this piece o code:

seems never to cause thread b to get access to the run method.
The output is following:

and there's never any output from thread b.

Thanks,
Justyna Wozniak
Valentin Mone
Greenhorn

Joined: Nov 05, 2006
Posts: 24
Is it because you're running an endless loop? both thread a and b require the same lock on "runnable" object. To me it seems that the one thread that acquires the lock will run forever. It is not guaranteed that the thread "a" will run always first, but in your case it did. Am I wrong?
Rohit Dhodapkar
Ranch Hand

Joined: Apr 27, 2006
Posts: 38
Its because
1. Thread a and b both are created by the same object .
2. THe run method is syncronized.
So in your code thread a enters into a infinite for loop and never finshes. So thread b can't enter the run method.

Try this code. It would be more clear

public class RunnableTest implements Runnable{
static int x, y;
public synchronized void run(){
for(int i= 0 ;i<100 ;i++) {
x++;
y++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(x+" "+y + " " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
RunnableTest runnable = new RunnableTest();
Thread a = new Thread(runnable);
a.setName("a");
Thread b = new Thread(runnable);
b.setName("b");
a.start();
b.start();
}
}
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
...

or instead of the sleep(), you can use

Thread.yield();



Yours,
Bu.


all events occur in real time
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, the thing is that the run() method is synchronized, so yield() will have no effect since the other thread can't acquire the lock it would need in order to run(). Likewise sleep() doesn't give up the lock, so whichever thread gets the lock first will retain it, forever. For comparison, you could simply remove the synchronized keyword. But that may yield hard-to-understand results, as you than would have two threads accessing shared mutable data (x and y) without synchronization. Or you could modify the run() method so that the access to x and y is still synchronized, but the sync lock isn't held permanently. For example:

Now every time the loop repeats, the lock will be released (by exiting the sync block) and then re-acquired (by re-entering it). This will give the other thread an opportunity to grab the lock. That should be enough to allow both threads to run, intermittently at least. Adding the yield() statement (outside the sync block) probably isn't necessary, but may make it more likely that the threads will alternate in a somewhat fair fashion, rather than one thread hogging all the time.
[ November 05, 2006: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi ranchers,

Jim Yingst posted November 05, 2006 11:25 AM
Well, the thing is that the run() method is synchronized, so yield() will have no effect since the other thread can't acquire the lock it would need in order to run(). Likewise sleep() doesn't give up the lock, (...)


True, but we wanted the sleep or yield method called not in an endless loop but in a short loop.

OK, both have no effect in a synchronized method, but it is usefull when you're testing the effect with / without synchronize.

As without yield or sleep the short loop
for(int i= 0 ;i<100 ;i++) { ... in Rohit's code, the loop will so fast be over, that the other thread never interrupts the first, synchronized or not.
So you won't see a difference in the output with or without synchronization.
The sleep or yield is only for this test.


Yours,
Bu.
Atul Shukla
Ranch Hand

Joined: Oct 09, 2006
Posts: 34
on calling Thread.yield(), thread retains the lock ...as Thread.sleep() retains ?
both retain lock ?
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
I think, only wait() will give up the lock.


Yours,
Bu.
 
 
subject: 2 thread instances using the same Runnable object
 
Similar Threads
Compile Error : cannot find symbol constructor Thread(Runnable)
Interrupting a Thread
Thread program not compiling
When both Thread and Runnable have public void run
Threads doubt??