如何检查线程是否在ExecutorService线程池中运行

bra*_*ram 8 java multithreading executorservice

我如何检查一个线程是否在线程ExecutorService池中运行?

背景:
如果设置了标志,我想在线程池中的线程之间进行同步.因此,如果将标志设置为true以进行同步,那么我必须检查其他线程是否正在运行或等待其完成,然后使用synchronize调用阻塞线程,以便其他线程等待此阻塞线程完成.

如果未设置flag,则无需同步,并且可以并行执行线程.

谢谢!

Bor*_*der 6

你需要使用一个Semaphore.

这允许您有许多"许可"来做工作.如果您只希望一次运行一个任务,那么请Semaphore使用一个许可,否则Semaphore使用的许可数大于Thread池中的s 数.

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);
}
Run Code Online (Sandbox Code Playgroud)

这个例子有点人为,因为你可以只使用一个newSingleThreadExecutor()只需要一次运行的任务 - 但我想你知道这个并且出于某种原因不能.

编辑

我捅了一下,看看这是否可以整理,我遇到了这个.这提示了一个更简洁的解决方案:

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);
}
Run Code Online (Sandbox Code Playgroud)