Execute longtime threads in it's special order - java

Many time-consuming threads (500-900ms.) are created in the application.
They are to be executed in the order they have been created - one after another - not simultaneously. The execution should be processed in thread, that is not synchronized with main application thread.
I can't make small threads executed in an order, so I found a ThreadPoolExecutor, but think it's too heavy for my task. So I wrote my Executor class.
It works fine. You add a thread to the threadList and it start the Executor thread to execute small tasks, that can be added while execution.
Can you tell me it's drawbacks and maybe another better way to solve my problem.
import java.util.LinkedList;
import java.util.List;
public class SfourExecutor extends Thread implements Runnable {
private static List <Thread> threadList = new LinkedList<Thread>();
private static final SfourExecutor INSTANCE = new SfourExecutor();
public static List<Thread> getThreadList() {
return threadList;
}
public static void setThreadList(List<Thread> threadList) {
SfourExecutor.threadList = threadList;
}
public void addToThreadList(Thread thread) {
getThreadList().add(thread);
if (!this.isAlive()) {
this.start();
}
}
public static SfourExecutor getInstance() {
return SfourExecutor.INSTANCE;
}
private static class SfourHolder {
private static final SfourExecutor INSTANCE = new SfourExecutor();
}
SfourExecutor () {
}
#Override
public void run() {
LinkedList <Thread> tL = (LinkedList<Thread>) getThreadList();
while (!tL.isEmpty()) {
Thread t = tL.poll();
if (t!=null) {
t.start();
try {
t.join();
} catch (InterruptedException ex) {
}
}
}
}
}

Won't an Executor created via Executors.newSingleThreadExecutor() meet your requirements exactly? "Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time."
Don't create new Thread instances when you don't need to execute jobs concurrently. Even if you are working with legacy code that has implemented some logic in a Thread class, you should be able to execute them as Runnable instances to the executor.
If you insist on using your own executor, you should know that your current implementation is not thread-safe. LinkedList is not a concurrent data structure, and since any code in the process can add new jobs at any time, you have no way to ensure that all jobs are added to the list before your executor thread is started. Thus, changes to the list are not guaranteed to be visible to all of the threads that are working with it.

Why are you using threads instead of Runnables? Isn't it easier to have a list of Runnables and call run() on them instead than a list of thread and wait for each one to end?
Apart from this, your solution seems fine.
In both cases, I would only add some form of synchronization on addToThreadList and around the block that checks if there are tasks to execute in the run() method, since there is a possibility that the two pieces of code execute at the same time on the same linked list, which is not synchronized.

Actually, you should really consider using an Executor. I don't think you'll find it heavy:
int maxThreads = 1;
ExecutorService myService = Executors.newFixedThreadPool(maxThreads);
...
myService.execute(myRunnable);
Always avoid rewriting something that exists already. You'll avoid writing new bugs. For instance, your implementation is not Thread safe. 2 simultaneous calls to addToThreadList expose you too an illegalthreadstateexception.

Nice code, but Executors.newFixedThreadPool(nThreads) nice too. If your threads make long work (500-900ms) in your tasks - pool overhead not affect performance. And JIT and another JVM runtime optimization can work better with standard classes.

You have a problem in that once the thread list is empty, your processing thread will stop checking for new threads added to the list. Also, LinkedLists aren't safe for concurrent usage, so what one thread submits might not be seen by the executor thread (or worse, it might not show up the way you submitted it). If you used a LinkedBlockingQueue it would work better.
However, since you want everything to run in sequence, you don't need to create and start lots of new threads (which is pretty costly), you can just have one thread that runs lightweight Runnable tasks in order. ThreadPoolExecutor does this for you, and more, and it is also really easy to use if you take help from the Executors class (which uses ThreadPoolExecutors behind the scenes):
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Runnable(){
#Override
public void run(){
doSomethingThatTakesALongTime();
}
});
executorService.submit(new Runnable(){
#Override
public void run(){
doSomethingElseThatAlsoTakesALongTime();
}
});
Concurrency isn't easy, so I'd advice you to make use of the fact that Sun Oracle have experts employed full-time to write and maintain these libraries for you. That means you get more free time you can spend at the pub, with your family, or implementing new features for your customers.

Related

How can i wait on severals threads completed their code? [duplicate]

I'm making a Java application with an application-logic-thread and a database-access-thread.
Both of them persist for the entire lifetime of the application and both need to be running at the same time (one talks to the server, one talks to the user; when the app is fully started, I need both of them to work).
However, on startup, I need to make sure that initially the app thread waits until the db thread is ready (currently determined by polling a custom method dbthread.isReady()).
I wouldn't mind if app thread blocks until the db thread was ready.
Thread.join() doesn't look like a solution - the db thread only exits at app shutdown.
while (!dbthread.isReady()) {} kind of works, but the empty loop consumes a lot of processor cycles.
Any other ideas? Thanks.
Use a CountDownLatch with a counter of 1.
CountDownLatch latch = new CountDownLatch(1);
Now in the app thread do-
latch.await();
In the db thread, after you are done, do -
latch.countDown();
I would really recommend that you go through a tutorial like Sun's Java Concurrency before you commence in the magical world of multithreading.
There are also a number of good books out (google for "Concurrent Programming in Java", "Java Concurrency in Practice".
To get to your answer:
In your code that must wait for the dbThread, you must have something like this:
//do some work
synchronized(objectYouNeedToLockOn){
while (!dbThread.isReady()){
objectYouNeedToLockOn.wait();
}
}
//continue with work after dbThread is ready
In your dbThread's method, you would need to do something like this:
//do db work
synchronized(objectYouNeedToLockOn){
//set ready flag to true (so isReady returns true)
ready = true;
objectYouNeedToLockOn.notifyAll();
}
//end thread run method here
The objectYouNeedToLockOn I'm using in these examples is preferably the object that you need to manipulate concurrently from each thread, or you could create a separate Object for that purpose (I would not recommend making the methods themselves synchronized):
private final Object lock = new Object();
//now use lock in your synchronized blocks
To further your understanding:
There are other (sometimes better) ways to do the above, e.g. with CountdownLatches, etc. Since Java 5 there are a lot of nifty concurrency classes in the java.util.concurrent package and sub-packages. You really need to find material online to get to know concurrency, or get a good book.
Requirement ::
To wait execution of next thread until previous finished.
Next thread must not start until previous thread stops, irrespective of time consumption.
It must be simple and easy to use.
Answer ::
#See java.util.concurrent.Future.get() doc.
future.get() Waits if necessary for the computation to complete, and then retrieves its result.
Job Done!! See example below
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
public class ThreadTest {
public void print(String m) {
System.out.println(m);
}
public class One implements Callable<Integer> {
public Integer call() throws Exception {
print("One...");
Thread.sleep(6000);
print("One!!");
return 100;
}
}
public class Two implements Callable<String> {
public String call() throws Exception {
print("Two...");
Thread.sleep(1000);
print("Two!!");
return "Done";
}
}
public class Three implements Callable<Boolean> {
public Boolean call() throws Exception {
print("Three...");
Thread.sleep(2000);
print("Three!!");
return true;
}
}
/**
* #See java.util.concurrent.Future.get() doc
* <p>
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*/
#Test
public void poolRun() throws InterruptedException, ExecutionException {
int n = 3;
// Build a fixed number of thread pool
ExecutorService pool = Executors.newFixedThreadPool(n);
// Wait until One finishes it's task.
pool.submit(new One()).get();
// Wait until Two finishes it's task.
pool.submit(new Two()).get();
// Wait until Three finishes it's task.
pool.submit(new Three()).get();
pool.shutdown();
}
}
Output of this program ::
One...
One!!
Two...
Two!!
Three...
Three!!
You can see that takes 6sec before finishing its task which is greater than other thread. So Future.get() waits until the task is done.
If you don't use future.get() it doesn't wait to finish and executes based time consumption.
Good Luck with Java concurrency.
A lot of correct answers but without a simple example.. Here is an easy and simple way how to use CountDownLatch:
//inside your currentThread.. lets call it Thread_Main
//1
final CountDownLatch latch = new CountDownLatch(1);
//2
// launch thread#2
new Thread(new Runnable() {
#Override
public void run() {
//4
//do your logic here in thread#2
//then release the lock
//5
latch.countDown();
}
}).start();
try {
//3 this method will block the thread of latch untill its released later from thread#2
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//6
// You reach here after latch.countDown() is called from thread#2
public class ThreadEvent {
private final Object lock = new Object();
public void signal() {
synchronized (lock) {
lock.notify();
}
}
public void await() throws InterruptedException {
synchronized (lock) {
lock.wait();
}
}
}
Use this class like this then:
Create a ThreadEvent:
ThreadEvent resultsReady = new ThreadEvent();
In the method this is waiting for results:
resultsReady.await();
And in the method that is creating the results after all the results have been created:
resultsReady.signal();
EDIT:
(Sorry for editing this post, but this code has a very bad race condition and I don't have enough reputation to comment)
You can only use this if you are 100% sure that signal() is called after await(). This is the one big reason why you cannot use Java object like e.g. Windows Events.
The if the code runs in this order:
Thread 1: resultsReady.signal();
Thread 2: resultsReady.await();
then thread 2 will wait forever. This is because Object.notify() only wakes up one of the currently running threads. A thread waiting later is not awoken. This is very different from how I expect events to work, where an event is signalled until a) waited for or b) explicitly reset.
Note: Most of the time, you should use notifyAll(), but this is not relevant to the "wait forever" problem above.
Try CountDownLatch class out of the java.util.concurrent package, which provides higher level synchronization mechanisms, that are far less error prone than any of the low level stuff.
You could do it using an Exchanger object shared between the two threads:
private Exchanger<String> myDataExchanger = new Exchanger<String>();
// Wait for thread's output
String data;
try {
data = myDataExchanger.exchange("");
} catch (InterruptedException e1) {
// Handle Exceptions
}
And in the second thread:
try {
myDataExchanger.exchange(data)
} catch (InterruptedException e) {
}
As others have said, do not take this light-hearted and just copy-paste code. Do some reading first.
The Future interface from the java.lang.concurrent package is designed to provide access to results calculated in another thread.
Take a look at FutureTask and ExecutorService for a ready-made way of doing this kind of thing.
I'd strongly recommend reading Java Concurrency In Practice to anyone interested in concurrency and multithreading. It obviously concentrates on Java, but there is plenty of meat for anybody working in other languages too.
If you want something quick and dirty, you can just add a Thread.sleep() call within your while loop. If the database library is something you can't change, then there is really no other easy solution. Polling the database until is ready with a wait period won't kill the performance.
while (!dbthread.isReady()) {
Thread.sleep(250);
}
Hardly something that you could call elegant code, but gets the work done.
In case you can modify the database code, then using a mutex as proposed in other answers is better.
This applies to all languages:
You want to have an event/listener model. You create a listener to wait for a particular event. The event would be created (or signaled) in your worker thread. This will block the thread until the signal is received instead of constantly polling to see if a condition is met, like the solution you currently have.
Your situation is one of the most common causes for deadlocks- make sure you signal the other thread regardless of errors that may have occurred. Example- if your application throws an exception- and never calls the method to signal the other that things have completed. This will make it so the other thread never 'wakes up'.
I suggest that you look into the concepts of using events and event handlers to better understand this paradigm before implementing your case.
Alternatively you can use a blocking function call using a mutex- which will cause the thread to wait for the resource to be free. To do this you need good thread synchronization- such as:
Thread-A Locks lock-a
Run thread-B
Thread-B waits for lock-a
Thread-A unlocks lock-a (causing Thread-B to continue)
Thread-A waits for lock-b
Thread-B completes and unlocks lock-b
You could read from a blocking queue in one thread and write to it in another thread.
Since
join() has been ruled out
you have already using CountDownLatch and
Future.get() is already proposed by other experts,
You can consider other alternatives:
invokeAll from ExecutorService
invokeAll(Collection<? extends Callable<T>> tasks)
Executes the given tasks, returning a list of Futures holding their status and results when all complete.
ForkJoinPool or newWorkStealingPool from Executors ( since Java 8 release)
Creates a work-stealing thread pool using all available processors as its target parallelism level.
This idea can apply?. If you use CountdownLatches or Semaphores works perfect but if u are looking for the easiest answer for an interview i think this can apply.

How to wait for a thread that spawns it's own thread?

I'm trying to test a method that does it's work in a separate thread, simplified it's like this:
public void methodToTest()
{
Thread thread = new Thread()
{
#Override
public void run() {
Clazz.i = 2;
}
};
thread.start();
}
In my unit test I want to test that Clazz.i == 2, but I can't do this because I think that the assert is run before the thread changes the value. I thought of using another thread to test it and then use join to wait but it still doesn't work.
SSCCE:
#Test
public void sscce() throws InterruptedException
{
Thread thread = new Thread()
{
#Override
public void run() {
methodToTest()
}
};
thread.start();
thread.join();
AssertEquals(2, Clazz.i);
}
public static class Clazz
{
public static int i = 0;
}
I think this is because the test main code creates a thread that is waiting (joined) to the 2nd thread, but the 2nd thread doesn't do the work, it creates another thread to do the work and then finishes, which continues the first thread, while the third thread does the Clazz.i = 2 after the assertion.
How can I make it so that the first thread waits for the thread that it starts as well as any threads that that thread starts?
Without a reference to the thread created in methodToTest, you cannot, quite simply. Java provides no mechanism for finding "threads that were spawned during this particular time period" (and even if it did, it would arguably be an ugly mechanism to use).
As I see it, you have two choices:
Make methodToTest wait for the thread it spawns. Of course, if you explicitly want this to be an asynchronous action, then you can't very well do that.
Return the newly created thread from methodToTest, so that any callers can choose to wait for it if they so wish.
It may be noted that the second choice can be formulated in a few different ways. You could, for instance, return some abstract Future-like object rather than a thread, if you want to extend the liberty of methodToTest to use various ways of doing asynchronous work. You could perhaps also define some global task-pool that you enforce all your asynchronous tasks to run inside, and then wait for all tasks in the pool to finish before checking the assertion. Such a task pool could take the form of an ExecutorService, or a ThreadGroup, or any number of other forms. They all do the same thing in the end, but may be more or less suited to your environment -- the main point being that you have to explicitly give the caller access to the newly created thread, is some manner or another.
Since your threads seems to be performing different operations, you can use CountDownLatch to solve your problem.
Declare a CountDownLatch in main thread and pass this latch object to other threads. use await() in main thread and decrement latch in other threads.
In Main thread: ( first thread)
CountDownLatch latch = new CountDownLatch(2);
/* Create Second thread and pass the latch. Pass the same latch from second
thread to third thread when you are creating third thread */
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Pass this latch to second and third threads and use countdown in these threads
In second and third threads,
try {
// add your business logic i.e. run() method implementation
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
Have a look this article for better understanding.
ExecutorService invokeAll() API is other preferable solution.
You can't unit-test functionality that the unit does not provide.
You're saying that you want to verify that methodToTest() eventually sets Clazz.i=2, but what does "eventually" mean? Your methodToTest() function does not provide its caller with any way to know when Clazz.i has been set. The reason you're having a hard time figuring out how to test the feature is because your module does not provide that feature.
This might be a good time for you to read up on Test Driven Development (TDD). That's where you write the tests first, and then you write code that makes the tests pass. Writing the tests first helps you to paint a clearer picture of whatever it is that you want the module to do.
It also has a side benefit: If you practice strict TDD (i.e., if you never write any module code except to make a test pass), then your test coverage will be 100%.
And, that leads to another side benefit: If you have 100% test coverage, then you can refactor without fear because if you break anything at all, your unit tests will tell you so.

Why can't a Java Thread object be restarted?

I know that it is not possible to restart a used Java Thread object, but I don't find an explanation why this is not allowed; even if it is guaranteed that the thread has finished (see example code below).
I don't see why start() (or at least a restart()) method should not be able to somehow reset the internal states - whatever they are - of a Thread object to the same values they have when the Thread object is freshly created.
Example code:
class ThreadExample {
public static void main(String[] args){
Thread myThread = new Thread(){
public void run() {
for(int i=0; i<3; i++) {
try{ sleep(100); }catch(InterruptedException ie){}
System.out.print(i+", ");
}
System.out.println("done.");
}
};
myThread.start();
try{ Thread.sleep(500); }catch(InterruptedException ie){}
System.out.println("Now myThread.run() should be done.");
myThread.start(); // <-- causes java.lang.IllegalThreadStateException
} // main
} // class
I know that it is not possible to
restart a used Java Thread object, but
I don't find an explanation why this
is not allowed; even if it is
guaranteed that the thread has
finished (see example code below).
My guestimation is that Threads might be directly tied (for efficiency or other constrains) to actual native resources that might be re-startable in some operating systems, but not in others. If the designers of the Java language had allowed Threads to be re-started, they might limit the number of operating systems on which the JVM can run.
Come to think of it, I cannot think of a OS that allows a thread or process to be restarted once it is finished or terminated. When a process completes, it dies. You want another one, you restart it. You never resurrect it.
Beyond the issues of efficiency and limitations imposed by the underlying OS, there is the issue of analysis and reasoning. You can reason about concurrency when things are either immutable or have a discrete, finite life-time. Just like state machines, they have to have a terminal state. Is it started, waiting, finished? Things like that cannot be easily reasoned about if you allow Threads to resurrect.
You also have to consider the implications of resurrecting a thread. Recreate its stack, its state, is is safe to resurrect? Can you resurrect a thread that ended abnormally? Etc.
Too hairy, too complex. All that for insignificant gains. Better to keep Threads as non-resurrectable resources.
I'd pose the question the other way round - why should a Thread object be restartable?
It's arguably much easier to reason about (and probably implement) a Thread that simply executes its given task exactly once and is then permanently finished. To restart threads would require a more complex view on what state a program was in at a given time.
So unless you can come up with a specific reason why restarting a given Thread is a better option than just creating a new one with the same Runnable, I'd posit that the design decision is for the better.
(This is broadly similar to an argument about mutable vs final variables - I find the final "variables" much easier to reason about and would much rather create multiple new constant variables rather than reuse existing ones.)
Because they didn't design it that way. From a clarity standpoint, that makes sense to me. A Thread represents a thread of execution, not a task. When that thread of execution has completed, it has done its work and it just muddies things were it to start at the top again.
A Runnable on the other hand represents a task, and can be submitted to many Threads as many times as you like.
Why don't you want to create a new Thread? If you're concerned about the overhead of creating your MyThread object, make it a Runnable and run it with a new Thread(myThread).start();
Java Threads follow a lifecycle based on the State Diagram below. Once the thread is in a final state, it is over. That is simply the design.
You can kind of get around this, either by using a java.util.concurrent.ThreadPoolExecutor, or manually by having a thread that calls Runnable.run() on each Runnable that it is given, not actually exiting when it is finished.
It's not exactly what you were asking about, but if you are worried about thread construction time then it can help solve that problem. Here's some example code for the manual method:
public class ReusableThread extends Thread {
private Queue<Runnable> runnables = new LinkedList<Runnable>();
private boolean running;
public void run() {
running = true;
while (running) {
Runnable r;
try {
synchronized (runnables) {
while (runnables.isEmpty()) runnables.wait();
r = runnables.poll();
}
}
catch (InterruptedException ie) {
// Ignore it
}
if (r != null) {
r.run();
}
}
}
public void stopProcessing() {
running = false;
synchronized (runnables) {
runnables.notify();
}
}
public void addTask(Runnable r) {
synchronized (runnables) {
runnables.add(r);
runnables.notify();
}
}
}
Obviously, this is just an example. It would need to have better error-handling code, and perhaps more tuning available.
If you are concerned with the overhead of creating a new Thread object then you can use executors.
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Testes {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Testes.A());
executor.execute(new Testes.A());
executor.execute(new Testes.A());
}
public static class A implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getId());
}
}
}
Running this you will see that the same thread is used for all Runnable objects.
A Thread is not a thread. A thread is an execution of your code. A Thread is an object that your program uses to create and, manage the life-cycle of, a thread.
Suppose you like playing tennis. Suppose you and your friend play a really awesome set. How would your friend react if you said, "That was incredible, let's play it again." Your friend might think you were nuts. It doesn't make sense even to talk about playing the same set again. If you play again you're playing a different set.
A thread is an execution of your code. It doesn't make sense to even talk about "re-using" a thread of execution for same reason that it makes no sense to talk about re-playing the same set in tennis. Even if another execution of your code executes all the same statements in the same order, it's still a different execution.
Andrzej Doyle's asked, "Why would you want to re-use a Thread?" Why indeed? If a Thread object represents a thread of execution---an ephemeral thing that you can't even talk about re-using---then why would you want or expect the Thread object to be re-useable?
i've been searching the same solution which you seem to be looking for, and i resolved it in this way. if you occur mousePressed Event you can terminate it also reuse it, but it need to be initialized, as you can see below.
class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
if(th.isAlive()){
th.interrupt();
th = new Thread();
}
else{
th.start();
}
}
}

java background task

I was wondering which would be the most efficient approach to implement some kind of background task in java (I guess that would be some kind of nonblocking Threads). To be more precise - I have some java code and then at some point I need to execute a long running operation. What I would like to do is to execute that operation in the background so that the rest of the program can continue executing and when that task is completed just update some specific object which. This change would be then detected by other components.
You want to make a new thread; depending on how long the method needs to be, you can make it inline:
// some code
new Thread(new Runnable() {
#Override public void run() {
// do stuff in this thread
}
}).start();
Or just make a new class:
public class MyWorker extends Thread {
public void run() {
// do stuff in this thread
}
}
// some code
new MyWorker().start();
You should use Thread Pools,
http://java.sun.com/docs/books/tutorial/essential/concurrency/pools.html
Naïve idea : you might be able to create Thread, give it a low priority, and do a loop of :
doing a little bit of work
using yield or sleep to let other threads work in parrallel
That would depend on what you actually want to do in your thread
Yes, you're going to want to spin the operation off on to it's own thread. Adding new threads can be a little dangerous if you aren't careful and aware of what that means and how resources will interact. Here is a good introduction to threads to help you get started.
Make a thread. Mark this thread as Daemon. The JVM exits when the only thread running are all daemon threads.

Getting the output of a Thread

What do you think is the best way for obtaining the results of the work of a thread? Imagine a Thread which does some calculations, how do you warn the main program the calculations are done?
You could poll every X milliseconds for some public variable called "job finished" or something by the way, but then you'll receive the results later than when they would be available... the main code would be losing time waiting for them. On the other hand, if you use a lower X, the CPU would be wasted polling so many times.
So, what do you do to be aware that the Thread, or some Threads, have finished their work?
Sorry if it looks similar to this other question, that's probably the reason for the eben answer, I suppose. What I meant was running lots of threads and know when all of them have finished, without polling them.
I was thinking more in the line of sharing the CPU load between multiple CPU's using batches of Threads, and know when a batch has finished. I suppose it can be done with Futures objects, but that blocking get method looks a lot like a hidden lock, not something I like.
Thanks everybody for your support. Although I also liked the answer by erickson, I think saua's the most complete, and the one I'll use in my own code.
Don't use low-level constructs such as threads, unless you absolutely need the power and flexibility.
You can use a ExecutorService such as the ThreadPoolExecutor to submit() Callables. This will return a Future object.
Using that Future object you can easily check if it's done and get the result (including a blocking get() if it's not yet done).
Those constructs will greatly simplify the most common threaded operations.
I'd like to clarify about the blocking get():
The idea is that you want to run some tasks (the Callables) that do some work (calculation, resource access, ...) where you don't need the result right now. You can just depend on the Executor to run your code whenever it wants (if it's a ThreadPoolExecutor then it will run whenever a free Thread is available). Then at some point in time you probably need the result of the calculation to continue. At this point you're supposed to call get(). If the task already ran at that point, then get() will just return the value immediately. If the task didn't complete, then the get() call will wait until the task is completed. This is usually desired since you can't continue without the tasks result anyway.
When you don't need the value to continue, but would like to know about it if it's already available (possibly to show something in the UI), then you can easily call isDone() and only call get() if that returns true).
You could create a lister interface that the main program implements wich is called by the worker once it has finished executing it's work.
That way you do not need to poll at all.
Here is an example interface:
/**
* Listener interface to implement to be called when work has
* finished.
*/
public interface WorkerListener {
public void workDone(WorkerThread thread);
}
Here is an example of the actual thread which does some work and notifies it's listeners:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Thread to perform work
*/
public class WorkerThread implements Runnable {
private List listeners = new ArrayList();
private List results;
public void run() {
// Do some long running work here
try {
// Sleep to simulate long running task
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
results = new ArrayList();
results.add("Result 1");
// Work done, notify listeners
notifyListeners();
}
private void notifyListeners() {
for (Iterator iter = listeners.iterator(); iter.hasNext();) {
WorkerListener listener = (WorkerListener) iter.next();
listener.workDone(this);
}
}
public void registerWorkerListener(WorkerListener listener) {
listeners.add(listener);
}
public List getResults() {
return results;
}
}
And finally, the main program which starts up a worker thread and registers a listener to be notified once the work is done:
import java.util.Iterator;
import java.util.List;
/**
* Class to simulate a main program
*/
public class MainProg {
public MainProg() {
WorkerThread worker = new WorkerThread();
// Register anonymous listener class
worker.registerWorkerListener(new WorkerListener() {
public void workDone(WorkerThread thread) {
System.out.println("Work done");
List results = thread.getResults();
for (Iterator iter = results.iterator(); iter.hasNext();) {
String result = (String) iter.next();
System.out.println(result);
}
}
});
// Start the worker thread
Thread thread = new Thread(worker);
thread.start();
System.out.println("Main program started");
}
public static void main(String[] args) {
MainProg prog = new MainProg();
}
}
Polling a.k.a busy waiting is not a good idea. As you mentioned, busy waiting wastes CPU cycles and can cause your application to appear unresponsive.
My Java is rough, but you want something like the following:
If one thread has to wait for the output of another thread you should make use of a condition variable.
final Lock lock = new ReentrantLock();
final Condition cv = lock.newCondition();
The thread interested in the output of the other threat should call cv.wait(). This will cause the current thread to block. When the worker thread is finished working, it should call cv.signal(). This will cause the blocked thread to become unblocked, allowing it to inspect the output of the worker thread.
As an alternative to the concurrency API as described by Saua (and if the main thread doesn't need to know when a worker thread finishes) you could use the publish/subscribe pattern.
In this scenario the child Thread/Runnable is given a listener that knows how to process the result and which is called back to when child Thread/Runnable completes.
Your scenario is still a little unclear.
If you are running a batch job, you may want to use invokeAll. This will block your main thread until all the tasks are complete. There is no "busy waiting" with this approach, where the main thread would waste CPU polling the isDone method of a Future. While this method returns a list of Futures, they are already "done". (There's also an overloaded version that can timeout before completion, which might be safer to use with some tasks.) This can be a lot cleaner than trying to gather up a bunch of Future objects yourself and trying to check their status or block on their get methods individually.
If this is an interactive application, with tasks sporadically spun off to be executed in the background, using a callback as suggested by nick.holt is a great approach. Here, you use the submit a Runnable. The run method invokes the callback with the result when it's been computed. With this approach, you may discard the Future returned by submit, unless you want to be able to cancel running tasks without shutting down the whole ExecutorService.
If you want to be able to cancel tasks or use the timeout capabilities, an important thing to remember is that tasks are canceled by calling interrupt on their thread. So, your task needs to check its interrupted status periodically and abort as needed.
Subclass Thread, and give your class a method that returns the result. When the method is called, if the result hasn't been created, yet, then join() with the Thread. When join() returns, your Thread's work will be done and the result should be available; return it.
Use this only if you actually need to fire off an asynchronous activity, do some work while you're waiting, and then obtain the result. Otherwise, what's the point of a Thread? You might as well just write a class that does the work and returns the result in the main thread.
Another approach would be a callback: have your constructor take an argument that implements an interface with a callback method that will be called when the result is computed. This will make the work completely asynchronous. But if you at all need to wait for the result at some point, I think you're still going to need to call join() from the main thread.
As noted by saua: use the constructs offered by java.util.concurrent. If you're stuck with a pre 1.5 (or 5.0) JRE, you ,might resort to kind of rolling your own, but you're still better of by using a backport: http://backport-jsr166.sourceforge.net/

Categories

Resources