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.
Tom Hawtin - 22 Jan 2007 21:11 GMT
> 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
Daniel Pitts - 22 Jan 2007 21:25 GMT
> Hi,
>
[quoted text clipped - 20 lines]
>
> 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.
Damo - 22 Jan 2007 21:42 GMT
> 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.
Lew - 22 Jan 2007 23:28 GMT
> Hi,
>
[quoted text clipped - 11 lines]
> 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
Damo - 22 Jan 2007 23:45 GMT
> 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
Damo - 22 Jan 2007 23:54 GMT
Sorry the code is:
> synchronize(resultList)
> {
[quoted text clipped - 3 lines]
> }
> }
Lew - 23 Jan 2007 03:53 GMT
> 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
Lew wrote:
>> 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 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
Damo - 22 Jan 2007 23:50 GMT
> 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
Patricia Shanahan - 22 Jan 2007 23:59 GMT
>> Have you actually tried running this code exactly as you presented it to us?
>> Doesn't the getList() call give you a compiler error?
[quoted text clipped - 16 lines]
>
> 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
Damo - 23 Jan 2007 00:10 GMT
Its working and faster now
Thanks for the help all