Hello,
I am trying to implement multithreading in java for the first time, and I
find that my threads do not want to share system resources, I cannot get
them to run concurrently. Each thread insists on finishing all the way
before another wants to execute, despite my attempts at wait(), sleep() or
yield().
I have extracted a simple demonstration of my problem below:
package trypo.apps.testarea;
public class Test2 {
public static void main(String[] args) throws InterruptedException {
TestThread a = new TestThread("Test1", 10, 13);
TestThread b = new TestThread("Test2", 20, 23);
a.join();
b.join();
}
}
Class Test2 starts 2 separate threads that should count up towards a
maxvalue.
package trypo.apps.testarea;
public class TestThread extends Thread {
private int countValue;
private int maxValue;
public TestThread(String newName, int InitValue, int maxValue) {
super(newName);
this.countValue = InitValue;
this.maxValue = maxValue;
this.run();
}
public void run() {
while (this.countValue < this.maxValue) {
System.out.println(this.getName()+" value "+this.countValue);
this.countValue++;
yield();
}
}
}
Class TestThread is an extension of Thread which performs an "endless" loop
in run(), however for each loop it calls yield() to give the other thread a
chance to run.
I get the following output:
Test1 value 10
Test1 value 11
Test1 value 12
Test2 value 20
Test2 value 21
Test2 value 22
...which tells me that thread Test1 completes its run() method completely
before Test2 even got a single loop done. This holds true also if I add more
threads, and/or a wider count interval - the thread that starts first
finishes before anything else can start followed by the next and so on. I
specifically need my threads to execute "simulatenously" so they can
exchange information and go about their separate business most of the time.
I am initially trying to execute this in Eclipse 3.2.2, but I have attempted
to execute the code from the prompt (I am running WinXP), with the same
result.
This is my version info:
C:\>java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)
Can you help me spot what i'm missing here ?
Thanks in advance !!
Morten
Patricia Shanahan - 09 Oct 2007 21:38 GMT
> Hello,
>
[quoted text clipped - 3 lines]
> before another wants to execute, despite my attempts at wait(), sleep() or
> yield().
...
> public TestThread(String newName, int InitValue, int maxValue) {
> super(newName);
> this.countValue = InitValue;
> this.maxValue = maxValue;
> this.run();
> }
this.run() is a normal call to the run method. Change it to start(),
which creates a new thread that runs the run method.
Patricia
Morty - 09 Oct 2007 21:41 GMT
> this.run() is a normal call to the run method. Change it to start(),
> which creates a new thread that runs the run method.
>
> Patricia
Fantastic, I knew it had to be a rather small thing I had missed. That did
the trick.
Thanks..
Lew - 09 Oct 2007 23:29 GMT
>> this.run() is a normal call to the run method. Change it to start(),
>> which creates a new thread that runs the run method.
Also, take it out of the constructor.
Do not do work in constructors. Constructors are for construction.
In your example, the start() calls should happen inside the Test2.main().

Signature
Lew
Lew - 09 Oct 2007 23:34 GMT
> package trypo.apps.testarea;
> public class TestThread extends Thread {
[quoted text clipped - 5 lines]
> this.maxValue = maxValue;
> this.run();
[sic]
> }
> public void run() {
[quoted text clipped - 5 lines]
> }
> }
'yield()' is a static method. To avoid confusion, always invoke static
entities through their class, thus:
Thread.yield();

Signature
Lew
Lew - 09 Oct 2007 23:40 GMT
Morty wrote:
>> public void run() {
>> while (this.countValue < this.maxValue) {
[quoted text clipped - 4 lines]
>> }
>> }
> 'yield()' is a static method. To avoid confusion, always invoke static
> entities through their class, thus:
>
> Thread.yield();
And that might not even help you, since yield() is not guaranteed to cause a
thread to yield its timeslice.
> Thread.yield is a purely heuristic hint advising the JVM that
> if there are any other runnable but non-running threads, the
> scheduler should run one or more of these threads rather than
> the current thread.
> The JVM may interpret this hint in any way it likes.
<http://g.oswego.edu/dl/cpj/mechanics.html>
excerpted from Doug Lea's excellent /Concurrent Programming in Java/, which
goes on to say,
> On JVM implementations that employ pre-emptive scheduling
> policies, especially those on multiprocessors, it is possible
> and even desirable that
> the scheduler will simply ignore this hint provided by yield.

Signature
Lew