Java: How to wake a thread on demand?

Let's say I want to create an object that basically starts a thread endlessly. I want the thread to sleep, while there is no need for it, but when there is a need to do a certain job, it wakes up the thread - performs the task and returns to sleep. I also want the jobs to be queued and executed in the order in which they arrive. In cocoa / object c there is an NSOperationQueue for this. I wonder if java has something like this.

What do you think?

+6
source share
5 answers

I would use ExecutorService for example

private final ExecutorService executor = Executors.newSingleThreadExecutor(); public void task(final int arg) { executor.execute(new Runnable() { @Override public void run() { // perform task using `arg` } }); } 

It has a built-in thread that wakes up when tasks are added and sleep, when there are no remaining tasks, Blocking queues for queue tasks.

+4
source

I think a combination of BlockingQueue and ThreadPoolExecutor will do what you need.

Or, if you deploy a Java EE application server, you can use JMS and a message-driven bean.

+4
source

You can use some BlockingQueue .

When you read from a queue (in a stream), you either receive the next element, or if it is empty, wait until it is received.

This is actually you do not sleep the thread, but use the property of blocking the queue. For instance:

 private BlockingQueue queue; @Override public void run() { while(true) { handle(queue.poll()); } } 

The above code is in Runnable - you can use the ExecutorService to start in an executable, or old-fashioned way with Thread

The queue, of course, is set from the outside and filled (again from the outside) by incoming elements.

+3
source

You can find what you need in the java.util.concurrent library - this is a higher level API than Thread . Take a look at http://www.ibm.com/developerworks/java/library/j-jtp1126/index.html

+1
source

Since you want something similar to NSOperationQueue, I am switching from Java ExecutorService a second time. I am not sure if the ExecutorService will interrogate or wait for an interrupt. If you need more control, there are approaches based on low-level interrupts, according to 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(); } } 
0
source

Source: https://habr.com/ru/post/889197/


All Articles