Reputation: 11937
Sorry for the confusing title, I'm not sure how to describe it in minimal words but basically what I'm trying to do is return a LinkedList from a method. But I wanna put the actual content inside the method inside a Thread, and then return the data when the thread is done. Here is the code I am using:
public static LinkedList<Result> get(final String prefix){
final LinkedList<Result> results = new LinkedList<Result>();
if(thread != null){
thread.stop();
thread = null;
}
thread = new Thread(
new Runnable(){
public void run(){
try{
URL url = new URL(String.format(URL_INFO, prefix));
URLConnection connection = url.openConnection();
connection.setReadTimeout(Timeout.TIMEOUT);
connection.setConnectTimeout(Timeout.TIMEOUT);
InputStream is = connection.getInputStream();
Scanner reader = new Scanner(is);
while(reader.hasNextLine()){
String line = reader.nextLine();
if(line != null){
if(line.contains(String.format(WORDS_INFO, prefix))){
String[] s = line.split(String.format(PREFIX_INFO, prefix));
String[] s2 = s[1].split("\">");
if(s2.length > 0){
for(int i = 1; i < s2.length; i++){
String l = s2[i];
String[] split = l.split(FINAL_SPLIT);
results.add(new Result(prefix, split[0].trim()));
}
}
break;
}
}
}
reader.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
);
thread.start();
return results;
}
The thread is statically defined inside the variables section. And basically the problem here is that it returns an empty LinkedList because it's not waiting for the Thread to be finished. How can I wait until the Thread is finished before returning the LinkedList? Any help would be greatly appreciated. Thanks.
NOTE: The issue is not anything to do with reading the URL, the problem is is that it's returning an empty LinkedList because the Thread has not finished yet and I want to know how to wait until the Thread is done before it returns something.
Upvotes: 0
Views: 197
Reputation: 116878
I'm not sure why you are using a thread here at all. If you have to fork the thread and then wait for it to finish, then you should just execute the run()
code directly in the parent thread.
It is also important to realize that when you do something like:
final LinkedList<Result> results = new LinkedList<Result>();
thread = new Thread(
new Runnable(){
public void run(){
...
results.add(new Result(prefix, split[0].trim()));
...
return results;
You are using the results
object in a non-thread-safe manner. results
is not a synchronized collection so you would need to synchronize on it both in the Runnable
and in the outer thread if you actually wanted to return it while the thread was still running. Otherwise two threads are accessing the object without memory synchronization. Since you may now be calling join()
on the thread before returning, this would be a non issue since join()
will synchronize for you. But it is important to realize the ramifications there.
Lastly, thread.stop()
is deprecated. The right way to interrupt a thread is to call thread.interrupt()
which sets the interrupt flag on the thread and causes Thread.sleep()
, wait()
, and some other methods to throw InterruptedException
.
Upvotes: 1
Reputation: 28752
You need to wait till the thread completes execution. Look up the documentation on Thread.join
.
This is just one way to do what you are trying. There are many others, such as ExecutorService
Upvotes: 1