java - 如何正确管理单线程执行?

标签 java multithreading concurrency executorservice single-threaded

我有一个流程,希望由不同的来源触发。

假设我们有一种情况,我们有一些其他进程(我们称之为“manualStarter”)在某些条件下想要触发这个主进程。主要过程需要一段时间才能完成,比如说 10 秒到 10 分钟。如果在 ManualStarter 尝试启动该进程时该进程已经在进行中,则该进程不应多次排队。触发主进程启动的第二个进程可以是“timedStarter”,它会偶尔触发该进程,但前提是该进程未运行,否则它不会将要触发的进程排队,而是会尝试一段时间后再次出现。

现在我尝试使用 isAlive() 和 join() 来实现这种进程管理器,但似乎 isAlive() 根本不可靠,直到它将其状态更改为 Activity 状态,该线程的 100 个线程可能会开始(有时会这样做)。看来我不能依赖它。

然后我尝试使用 SingleThreadExecutor 服务,它更接近我正在寻找的内容,它不会阻止任何内容,并且只允许单个线程执行该进程,所以这很好,但是我仍然不知道如何检查状态/正确锁定它,或者如何确保启动线程的队列不会大于 1。我读到一些信号量通常用于类似类型的任务,但我不确定如何我可以在这种情况下使用它们。

那么我怎样才能实现我想要的呢?我需要实现自己的ThreadPoolExecutor吗?我该怎么做?还有更好的办法吗?

最佳答案

只需使用共享标志,以便手动启动器知道线程是否正在运行。例如:

// Schedule this to run periodically via ScheduledExecutorService
class ManualStarter {
    private final AtomicBoolen isRunning = new AtomicBoolean(false);
    private ExecutorService exec = Executors.newSingleThreadedExecutor();

    public void run() {
        if (!isRunning.getAndSet(true)) {
            // It wasn't running so this will start it
            exec.submit(new MainProcess(isRunning));
        }
    }
}


class MainProcess extends Runnable {
   private final AtomicBoolean isRunning;

   MainProcess(AtomicBoolean isRunning) { this.isRunning = isRunning; }

   @Override
   public void run() {
       // do whatever it does
       isRunning.set(false);
   }
}

然后在某个地方安排主要的事情定期运行,例如:

ScheduledExectorService sched = Executors.newScheduledThreadPool(1);
ManualStarter starter = new ManualStarter();
// Every 10 seconds will check if MainProcess is running and will start
// it if it's not
sched..scheduleAtFixedRate(starter, 0, 10, SECONDS);

关于java - 如何正确管理单线程执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40333199/

相关文章:

java - 如何在 Java 7 中优雅地定义持续时间

java - 使用 javas xpath 获取唯一集

java线程: Thread.中断()不工作

java - 将 Dao 作为静态成员存储在类中是否安全?

java - ArrayList() 的多线程得到 ArrayIndexOutOfBoundsException

java - 我收到警告 "App is not indexable by Google Search; consider adding at least one Activity with an ACTION-VIEW intent filter. "

java - 提交表单数据后出现以下问题

java - 对不同的数据库建立不同的连接并将其放入列表中

C 客户端/服务器套接字错误

Java - 优雅地退出线程