Problem with Threads

D

Damo

Hi,

I'm trying to write a program using Threads. I want to pass a value
into the run() method of the Thread and I want to return an ArrayList
from the run method. I'm passing the value in via the constructor of
the threaded class and then using a getValue() method in the the run()
method to acces the value passed in
To retrieve the ArrayList I've declared it as an instance variable, and
in the run() method I'm adding to the ArrayList. Then I have a
getList() method to get the populated List.

I start the Thread like this:

Thread t = new Thread(parameter); //parameter is the value I'm
passing in.
t.start();
list = t.getList(); // This is the method I created to retrieve the
populated list

Its not returning a the list as I want. The list appears to be empty.
Is the above the right way to go about this. I'm particularly unsure
about the line list=t.getList() , after I call the start method.

Any help would be appreciated.
 
T

Tom Hawtin

Damo said:
I'm trying to write a program using Threads. I want to pass a value
into the run() method of the Thread and I want to return an ArrayList
from the run method. I'm passing the value in via the constructor of
the threaded class and then using a getValue() method in the the run()
method to acces the value passed in

It's generally a good idea not to extend Thread (or any other class that
you do not need to inherit from). Instead pass a Runnable.

If you use anonymous inner classes, you can avoid having to explicitly
pass in values.
Thread t = new Thread(parameter); //parameter is the value I'm
passing in.
t.start();
list = t.getList(); // This is the method I created to retrieve the
populated list

If you have just started the thread, it probably hasn't finished (or
started) populating the list yet

So:

final List<String> strs = new ArrayList<String>();
Thread thread = new Thread(new Runnable() { public void run() {
strs.add("a string");
}});
thread.start();
// Perhaps do something else here,
// otherwise there is little point in starting another thread.
thread.join();
System.err.println(strs);

Tom Hawtin
 
D

Daniel Pitts

Damo said:
Hi,

I'm trying to write a program using Threads. I want to pass a value
into the run() method of the Thread and I want to return an ArrayList
from the run method. I'm passing the value in via the constructor of
the threaded class and then using a getValue() method in the the run()
method to acces the value passed in
To retrieve the ArrayList I've declared it as an instance variable, and
in the run() method I'm adding to the ArrayList. Then I have a
getList() method to get the populated List.

I start the Thread like this:

Thread t = new Thread(parameter); //parameter is the value I'm
passing in.
t.start();
list = t.getList(); // This is the method I created to retrieve the
populated list

Its not returning a the list as I want. The list appears to be empty.
Is the above the right way to go about this. I'm particularly unsure
about the line list=t.getList() , after I call the start method.

Any help would be appreciated.

If you can use Java 1.5 (and I suggest that you should)
Look into the java.util.concurrent package.
Specifically, Instead of starting threads directly with Runnable
instances, use Callable and Executors
<http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Callable.html>

Baring that, you could do it this way:
class MyRunnable implements Runnable {
private int value;

private final List<MyResultClass> list = new
ArrayList<MyResultClass>();
boolean ready = false;
public MyRunnable(int value) {
this.value = value;
}

public void run() {

synchronize(list) {
try {
for (int i = 0; i < value; ++i) {
list.add(new MyResultClass(i));
}
} finally {
ready = true;
list.notifyAll();
}
}
}

public List<MyResultClass> getList() throws InterruptedException {
synchronize(list) {
while (!ready) {
list.wait();
}
}
}
}

Then you could do this:
MyRunnable myRunnable = new MyRunnable(value);
Thread t = new Thread(myRunnable);
t.start();
myRunnable.getList();

The only problem with this approach is that getList() waits (and it has
to wait anyway) for the thread to complete. This gives you nearly the
same effect as running this program without any threads.

In reality, you'd be better to have your worker (MyRunnable in my case)
fire some sort of event.

Hope this helps,
Daniel.
 
D

Damo

Daniel said:
The only problem with this approach is that getList() waits (and it has
to wait anyway) for the thread to complete. This gives you nearly the
same effect as running this program without any threads.


What I'm trying to implement is a metasearch engine. I have it working
without Threads , but its running extremely slowly. I think whats
slowing it down is opening the connections to each search engine,
retrieving the result pages and running JTidy on them before extracting
each result. JTidy seems to be slowing it down a lot.
If I use a thread for each engine and have them running simultaenously,
it would (hopefully!) speed up.
 
L

Lew

Damo said:
> Hi,
>
> I'm trying to write a program using Threads. I want to pass a value
> into the run() method of the Thread and I want to return an ArrayList
> from the run method. I'm passing the value in via the constructor of
> the threaded class and then using a getValue() method in the the run()
> method to acces the value passed in
> To retrieve the ArrayList I've declared it as an instance variable, and
> in the run() method I'm adding to the ArrayList. Then I have a
> getList() method to get the populated List.
>
> I start the Thread like this:
>
> Thread t = new Thread(parameter); //parameter is the value I'm
> passing in.

Is "parameter" a String or a Runnable? Because Thread single-argument
constructors only exist for those types.
> t.start();
> list = t.getList(); // This is the method I created to retrieve the
> populated list

Have you actually tried running this code exactly as you presented it to us?
Doesn't the getList() call give you a compiler error?

- Lew
 
D

Damo

Have you actually tried running this code exactly as you presented it to us?
Doesn't the getList() call give you a compiler error?
Ye , Ive tried it, it did'nt give a compile error. Its a servlet so it
just printed a blank screen.
The paramater being passed in is a string.

I've changed it around now to what Daniel Pitts suggested, but now it
gives me a compiler error at

synchronize(list)
{
while(!ready)
{
resultList.wait();
}
}
it claims to "cannot find symbol.......method synchronize()

I'm at a loss as to why its doing this
 
D

Damo

Have you actually tried running this code exactly as you presented it to us?
Doesn't the getList() call give you a compiler error?
Ye , Ive tried it, it did'nt give a compile error. Its a servlet so it
just printed a blank screen.
The paramater being passed in is a string.

I've changed it around now to what Daniel Pitts suggested, but now it
gives me a compiler error at

synchronize(list)
{
while(!ready)
{
resultList.wait();
}
}
it claims to "cannot find symbol.......method synchronize()

I'm at a loss as to why its doing this
 
P

Patricia Shanahan

Damo said:
Ye , Ive tried it, it did'nt give a compile error. Its a servlet so it
just printed a blank screen.
The paramater being passed in is a string.

I've changed it around now to what Daniel Pitts suggested, but now it
gives me a compiler error at

synchronize(list)
{
while(!ready)
{
resultList.wait();
}
}
it claims to "cannot find symbol.......method synchronize()

I'm at a loss as to why its doing this

There is a typo. The keyword is "synchronized" not "synchronize".

"synchronize" conforms to the identifier syntax, and is not a keyword,
so followed by a "(" it should be a method call, but the compiler cannot
find a method with that identifier.

I think there should be a place for a kind, intelligent, Java syntax
checker that is a bit more helpful that the current compiler.
"synchronize" in that context is far more likely to be a typo for the
keyword than for a method identifier.

Patricia
 
L

Lew

Damo said:
Thread t = new Thread(parameter); //parameter is the value I'm
passing in.
t.start();
list = t.getList(); // This is the method I created to retrieve the
populated list
Ye , Ive tried it, it did'nt give a compile error. Its a servlet so it
just printed a blank screen.
The paramater being passed in is a string.

I am at loss myself. You show the variable 't' declared as class Thread, but
Thread does not have a 'getList()' method. That should throw a compiler error.

It does for me.

A String argument to a Thread constructor provides the Thread's name.

- Lew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

threads and GUIs 18
threads with gtk gui problem 0
Logic Problem with BigInteger Method 2
Error with server 3
Synchronization with threads 4
Problem with Threads 2
Problem with KMKfw libraries 1
Threads 5

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top