简体   繁体   中英

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

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

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.
}

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 Thread s to Runnable s. 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?

This really doesn't make sense in the context of an ExecutorService thread-pool. The pool is executing your Runnable (or Callable ) classes. Maybe what you should be asking is if you can see if a particular job is running in the pool or not.

If you want to accomplish this then each of the jobs, at the front of the run() (or call() ) method can check some sort of synchronized object and wait or continue as necessary. It may also be that you could have multiple thread pools and divide up your jobs into smaller pieces so you can control which parts of your jobs run concurrently.

However, in general as @Ralf points out, what you are doing is against the whole point of the thread-pool. The whole point of thread-pools is that the jobs run asynchronously. If you require a lot of synchronization points then maybe you need to redesign.

If you give more details about your environment, we may be able to more specifically address your underlying question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM