How to check if a thread is running in the ExecutorService Thread pool

27,746

Solution 1

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);
}

Solution 2

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.

Solution 3

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.
}
Share:
27,746
bram
Author by

bram

Updated on October 29, 2020

Comments

  • bram
    bram over 3 years

    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!

  • Boris the Spider
    Boris the Spider over 7 years
    @Bhargav what effect?
  • Bhargav
    Bhargav over 7 years
    You know. making sure that only 1 task is running at anu given time
  • Boris the Spider
    Boris the Spider over 7 years
    @Bhargav given that it has a single Thread, how would it do anything else?