Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

2 thread instances using the same Runnable object

 
Justyna Wozniak
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 38
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1274
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
...

or instead of the sleep(), you can use

Thread.yield();



Yours,
Bu.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Burkhard Hassel
Ranch Hand
Posts: 1274
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
on calling Thread.yield(), thread retains the lock ...as Thread.sleep() retains ?
both retain lock ?
 
Burkhard Hassel
Ranch Hand
Posts: 1274
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think, only wait() will give up the lock.


Yours,
Bu.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic