【问题标题】:How to check if a thread is running in the ExecutorService Thread pool如何检查ExecutorService线程池中是否有线程正在运行
【发布时间】:2013-04-05 07:05:57
【问题描述】:

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

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

如果未设置标志,则无需同步,可以并行执行线程。

谢谢!

【问题讨论】:

  • 你能给我们一些关于你在做什么/为什么做的背景吗?
  • 试过thread.isAlive() ?
  • 什么意思?你的意思是 task 是否正在运行?在ExecutorService 中总会有Threads 活着。请发布您的代码,以便我们为您提供帮助,而不是猜测您可能需要什么。
  • @exabrial 添加了我的问题的背景。
  • 你能退后一步解释一下为什么你想要这个。尝试在不谈论您需要完成的细节的情况下提出问题。现在您的问题与特定的解决方案太相关了。

标签: java multithreading executorservice


【解决方案1】:

您需要使用Semaphore

这使您可以拥有许多“许可”来工作。如果您希望一次只运行一项任务,则拥有一个带有一个许可的 Semaphore,否则拥有一个许可数量大于池中 Threads 数量的 Semaphore

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

这个例子有点做作,因为当您一次只需要运行一项任务时,您可以使用 newSingleThreadExecutor() - 但我假设您知道这一点,但由于某种原因不能。

编辑

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

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

【讨论】:

  • @Bhargav 有什么作用?
  • 你知道的。确保在给定时间只有 1 个任务正在运行
  • @Bhargav 鉴于它有一个Thread,它还能做什么?
【解决方案2】:

简而言之,你没有。执行程序不应该以这种方式使用。如果您想手动管理线程,请在没有 Executors 的情况下进行。如果您使用 Executors,请将您的想法从 Threads 转移到 Runnables。使用同步或java.util.concurrent 中的任何高级抽象使您的 Runnable 或类和方法线程安全。

【讨论】:

    【解决方案3】:

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

    如果您只想知道线程是否在特定的ExecutorService 中运行,您可以使用特定的ThreadFactory 创建ExecutorService,并让它附加一些特殊属性到线程,例如特殊名称.

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

    然后,在线程中,您只需检查名称是否以您的前缀开头:

    if (Thread.currentThread().getName().startsWith(EXECUTOR_THREADNAME_PREFIX)) {
        // In executor.
    } else {
        // Not in executor.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-19
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多