What I am after is a compatible way to configure the use of a thread pool or not. Ideally the rest of the code should not be impacted at all. I could use a thread pool with 1 thread but that isn't quite what I want. Any ideas?
ExecutorService es = threads == 0 ? new CurrentThreadExecutor() : Executors.newThreadPoolExecutor(threads);
// es.execute / es.submit / new ExecutorCompletionService(es) etc
Java 8 style:
Executor e = Runnable::run;
You can use Guava's MoreExecutors.newDirectExecutorService(), or MoreExecutors.directExecutor() if you don't need an ExecutorService.
If including Guava is too heavy-weight, you can implement something almost as good:
public final class SameThreadExecutorService extends ThreadPoolExecutor {
private final CountDownLatch signal = new CountDownLatch(1);
private SameThreadExecutorService() {
super(1, 1, 0, TimeUnit.DAYS, new SynchronousQueue<Runnable>(),
new ThreadPoolExecutor.CallerRunsPolicy());
}
#Override public void shutdown() {
super.shutdown();
signal.countDown();
}
public static ExecutorService getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder {
static ExecutorService instance = createInstance();
}
private static ExecutorService createInstance() {
final SameThreadExecutorService instance
= new SameThreadExecutorService();
// The executor has one worker thread. Give it a Runnable that waits
// until the executor service is shut down.
// All other submitted tasks will use the RejectedExecutionHandler
// which runs tasks using the caller's thread.
instance.submit(new Runnable() {
#Override public void run() {
boolean interrupted = false;
try {
while (true) {
try {
instance.signal.await();
break;
} catch (InterruptedException e) {
interrupted = true;
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}});
return Executors.unconfigurableScheduledExecutorService(instance);
}
}
Here's a really simple Executor (not ExecutorService, mind you) implementation that only uses the current thread. Stealing this from "Java Concurrency in Practice" (essential reading).
public class CurrentThreadExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
ExecutorService is a more elaborate interface, but could be handled with the same approach.
I wrote an ExecutorService based on the AbstractExecutorService.
/**
* Executes all submitted tasks directly in the same thread as the caller.
*/
public class SameThreadExecutorService extends AbstractExecutorService {
//volatile because can be viewed by other threads
private volatile boolean terminated;
#Override
public void shutdown() {
terminated = true;
}
#Override
public boolean isShutdown() {
return terminated;
}
#Override
public boolean isTerminated() {
return terminated;
}
#Override
public boolean awaitTermination(long theTimeout, TimeUnit theUnit) throws InterruptedException {
shutdown(); // TODO ok to call shutdown? what if the client never called shutdown???
return terminated;
}
#Override
public List<Runnable> shutdownNow() {
return Collections.emptyList();
}
#Override
public void execute(Runnable theCommand) {
theCommand.run();
}
}
I had to use the same "CurrentThreadExecutorService" for testing purposes and, although all suggested solutions were nice (particularly the one mentioning the Guava way), I came up with something similar to what Peter Lawrey suggested here.
As mentioned by Axelle Ziegler here, unfortunately Peter's solution won't actually work because of the check introduced in ThreadPoolExecutor on the maximumPoolSize constructor parameter (i.e. maximumPoolSize can't be <=0).
In order to circumvent that, I did the following:
private static ExecutorService currentThreadExecutorService() {
CallerRunsPolicy callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();
return new ThreadPoolExecutor(0, 1, 0L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), callerRunsPolicy) {
#Override
public void execute(Runnable command) {
callerRunsPolicy.rejectedExecution(command, this);
}
};
}
You can use the RejectedExecutionHandler to run the task in the current thread.
public static final ThreadPoolExecutor CURRENT_THREAD_EXECUTOR = new ThreadPoolExecutor(0, 0, 0, TimeUnit.DAYS, new SynchronousQueue<Runnable>(), new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
}
});
You only need one of these ever.
Related
Faced the fact that when the database is unavailable, the queue grows because tasks stop running. What is the best way to set some timeout for tasks executed in method run()? May be there is some good approach with using ExecutorService?
#Service
public class AsyncWriter implements Writer, Runnable {
private LinkedBlockingQueue<Entry> queue = new LinkedBlockingQueue<>();
private volatile boolean terminate = false;
private AtomicInteger completedCounter = new AtomicInteger();
#PostConstruct
private void runAsyncWriter() {
Thread async = new Thread(this);
async.setName("Writer Thread");
async.setPriority(2);
async.start();
}
#Override
public void run() {
while (!terminate) {
try {
Entry entry = queue.take();
dao.save(entry);
completedCounter.incrementAndGet();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void write(Entry entry) {
queue.add(entry);
}
}
Maybe you can try RxJava
https://www.baeldung.com/rx-java
And you can set your aync funtions
Timeout in RxJava
Say I have this:
class Queue {
private static ExecutorService executor = Executors.newFixedThreadPool(1);
public void use(Runnable r){
Queue.executor.execute(r);
}
}
my question is - how can I define the thread that's used in the pool, specifically would like to override the interrupt method on thread(s) in the pool:
#Override
public void interrupt() {
synchronized(x){
isInterrupted = true;
super.interrupt();
}
}
Define how threads for the pool are created by specifying a ThreadFactory.
Executors.newFixedThreadPool(1, new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
return new Thread(r) {
#Override
public void interrupt() {
// do what you need
}
};
}
});
Sure, a ThreadFactory can be expressed by a lambda.
ThreadFactory factory = (Runnable r) -> new YourThreadClass(r);
If there is no additional setup needed for a thread (like making it a daemon), you can use a method reference. The constructor YourThreadClass(Runnable) should exist, though.
ThreadFactory factory = YourThreadClass::new;
I'd advise reading the docs of ThreadPoolExecutor and Executors. They are pretty informative.
I have a situation where i need to check if a certain condition is met and it needs to be periodically executed a certain number of times to check for the condition before it declares the condition as not met and between each execution there needs to be a delay/sleep interval.
Code Structure:
class checkCondition<T> implements Callable<T>{
#Override
public T call() {
//Do Stuff and return result
return result;
}
public class TaskRunner<T> {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public Future<T> runTask(checkCondiiton task, int times, long sleep){
while(times > 0){
future = executor.submit(task);
Thread.sleep(sleep);
times--;
}
return future;
}
}
}
Is the above implementation correct? If not, please advice on what would be better approach. I am new to ExecutorService and Java Concurrency.
Try using Executors.newSingleThreadScheduledExecutor()
Example:
public class FixedScheduledExcutor
{
public static void main(String[] args) throws InterruptedException
{
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
CountDownLatch latch = new CountDownLatch(5);
executorService.scheduleAtFixedRate(new MyRunner(latch), 5, 5, TimeUnit.SECONDS);
latch.await();
System.out.println("Shutting down service...");
executorService.shutdown();
}
}
class MyRunner implements Runnable
{
CountDownLatch latch;
MyRunner(CountDownLatch latch)
{
this.latch = latch;
}
#Override
public void run()
{
System.out.println("Do something : " + latch.getCount());
latch.countDown();
}
}
How do i check if a thread is running in the pool of thread ExecutorService?
Background:
I want to synchronize between the threads in the Thread pool if there is a flag set.
So if the flag is set to true for synchronization, then I have to check if other Threads are running or wait for its completion and then invoke the blocking thread with synchronize, so that other threads would wait for this blocking thread to finish.
If flag is not set then no need to synchronize and could execute the threads in parallel.
Thanks!
You need to use a Semaphore.
This allows you to have a number of "permits" to do work. If you only want one task running at a time then have a Semaphore with one permit, otherwise have a Semaphore with a number of permits greater than the number of Threads in the pool.
static class Worker implements Runnable {
final Semaphore semaphore;
public Worker(Semaphore semaphore) {
this.semaphore = semaphore;
}
#Override
public void run() {
try {
semaphore.acquire();
try {
//do stuff
} finally {
semaphore.release();
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
final int numThreads = 10;
final ExecutorService executorService = Executors.newFixedThreadPool(10);
final Semaphore semaphore;
boolean myflag = true;
if (myflag) {
semaphore = new Semaphore(1);
} else {
semaphore = new Semaphore(numThreads);
}
final Worker worker = new Worker(semaphore);
executorService.submit(worker);
}
This example is a little contrived as you can just use a newSingleThreadExecutor() when you only need one task to run at a time - but I assume you know that and for some reason cannot.
EDIT
Having poked around a little to see if this can be tidied I came across this. This hints at a neater solution:
static interface TaskBlocker {
void acquire();
void release();
}
static class Worker implements Runnable {
final TaskBlocker taskBlocker;
public Worker(TaskBlocker taskBlocker) {
this.taskBlocker = taskBlocker;
}
#Override
public void run() {
taskBlocker.acquire();
try {
//do stuff
} finally {
taskBlocker.release();
}
}
}
public static void main(String[] args) {
final int numThreads = 10;
final ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
final TaskBlocker taskBlocker;
boolean myflag = true;
if (myflag) {
taskBlocker = new TaskBlocker() {
final Lock lock = new ReentrantLock();
#Override
public void acquire() {
lock.lock();
}
#Override
public void release() {
lock.unlock();
}
};
} else {
taskBlocker = new TaskBlocker() {
#Override
public void acquire() {
}
#Override
public void release() {
}
};
}
final Worker worker = new Worker(taskBlocker);
executorService.submit(worker);
}
In short, you don't. Executors are not meant to be used that way. If you want to manage your threads manually, do it without Executors. If you use Executors, shift your thinking from Threads to Runnables. Make your Runnables or the Classes and methods thread-safe, using synchronization or any of the high-level abstractions in java.util.concurrent.
How do i check if a thread is running in the pool of thread ExecutorService?
If you just want to know if a thread is running in a specific ExecutorService, you can create the ExecutorService with a specific ThreadFactory and have it attach some special property to the thread, such as a special name.
private static final String EXECUTOR_THREADNAME_PREFIX = "ExecutorThread";
ThreadFactory threadFactory = new ThreadFactory() {
private final AtomicInteger id = new AtomicInteger(0);
#Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName(EXECUTOR_THREADNAME_PREFIX + "_" + id.incrementAndGet());
return thread;
}
};
myExecutor = Executors.newCachedThreadPool(threadFactory);
Then, in the thread, you simply check if the name starts with your prefix:
if (Thread.currentThread().getName().startsWith(EXECUTOR_THREADNAME_PREFIX)) {
// In executor.
} else {
// Not in executor.
}
I want a method that runs 2 or more methods in separate threads. I want be sure that method won't finish before all threads are done.
The best approach is to utilize the Executor Service API to manage a thread pool instead of starting an open-ended number of threads on your own.
ExecutorService pool = Executors.newCachedThreadPool();
for (Runnable r : new Runnable[] {
new R() { void r() { myMethod1(); }},
new R() { void r() { myMethod2(); }},
})
pool.execute(r);
pool.shutdown();
pool.awaitTermination(60, TimeUnit.SECONDS);
abstract class R implements Runnable
public final void run() { r(); }
abstract void r();
}
Note that it is not advisable to insist on every method running in its own, separate thread. Threads are quite heavyweight (each allocating a complete call stack) and performance actually decreases as the thread count increases far beyond the number of available processor cores.
I prefer something like this:
public static void runParallel(Runnable... runnables) throws InterruptedException {
final CountDownLatch done = new CountDownLatch(runnables.length);
for (final Runnable r: runnables) {
new Thread(new Runnable() {
public void run() {
try {
r.run();
} finally {
done.countDown();
}
}
}).start();
}
done.await();
}
An advantage of this approach is that it also works with thread pool (i.e. you can replace new Thread(...).start() with executor.submit(...)).
Also it allows you to use pre-existing thread pool, unlike solutions based on awaitTermination() that force you to create new pools for each invocation.
My solution is
Function:
public void runParallel(Runnable... runnables) throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>(runnables.length);
for (Runnable runnable :runnables) {
Thread th = new Thread(runnable);
threads.add(th);
th.start();
}
for (Thread th : threads) {
th.join();
}
Use:
runParallel(new Runnable() {
#Override
public void run() {
method1()
}
}, new Runnable() {
#Override
public void run() {
method2()
}
}
);
any better ideas? Maybe there is a shorter way that I'm not aware of ;)
Following the API given by damienix:
public void runParallel(Runnable... runnables) throws InterruptedException {
final ExecutorService pool = Executors.newFixedThreadPool(runnables.length);
for (Runnable runnable: runnables) {
pool.submit(runnable);
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.MINUTES);
}