Reputation: 9457
Let's say I want to create an object that basically runs a thread infinitely. I want the thread to sleep while there is no need for him, but when there is a need for certain job to be done, it wakes the thread - gets the job done and goes back to sleep. I also want the jobs to be queued and be executed in the order they arrive. In cocoa/objective c there is an NSOperationQueue for that. I wonder if java has something similar.
What do you think?
Upvotes: 6
Views: 2527
Reputation: 597076
You can use some BlockingQueue
.
When you read from the queue (in the thread), you either get the next item, or if it is empty - wait until one is received.
This you are not actually sleeping the thread, but using the queue's blocking property. For example:
private BlockingQueue queue;
@Override
public void run() {
while(true) {
handle(queue.poll());
}
}
The above code is in a Runnable
- you can use an ExecutorService
to start a runnable, or the old-fashioned way with a Thread
The queue of course is set externally, and is filled (again externally) with the incoming items.
Upvotes: 3
Reputation: 1971
Since you want something similar to the NSOperationQueue, I second going with Java's ExecutorService. I am not sure if ExecutorService polls or waits for an interrupt. If you need more control there are lower-level interrupt-driven approaches, along these lines:
class InterruptDriven {
private final ReentrantLock lock = new ReentrantLock(true);
private final Condition asynchronousTrigger = lock.newCondition();
private AtomicBoolean poisoned = new AtomicBoolean(false);
public void interrupt() {
final ReentrantLock lock = this.lock;
try {
lock.lockInterruptibly();
asynchronousTrigger.signal();
} catch (InterruptedException ex) {
....
} finally {
lock.unlock();
}
}
public void workerWait(){
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
if (!poisoned.get()) {
asynchronousTrigger.await();
... do some work here ...
}
} catch (InterruptedException ie) {
...
}
} finally {
lock.unlock();
}
}
Upvotes: 0
Reputation: 533492
I would use an ExecutorService like
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public void task(final int arg) {
executor.execute(new Runnable() {
@Override
public void run() {
// perform task using `arg`
}
});
}
This has a built in thread which wakes when a tasks is added and sleeps when there is no tasks left, a Blocking Queue for queue tasks.
Upvotes: 4
Reputation: 32407
You can find what you need in the java.util.concurrent
library - it's a higher level API than Thread
. Have a look at http://www.ibm.com/developerworks/java/library/j-jtp1126/index.html
Upvotes: 1
Reputation: 308753
I think a combination of a BlockingQueue
and a ThreadPoolExecutor
will do what you need.
Or, if you deploy on a Java EE app server, you could use JMS and a message-driven bean.
Upvotes: 4