如何确保单个Runnable任务不会在两个线程上同时运行

时间:2014-10-21 05:25:09

标签: java concurrency executorservice

例如如果我有两个线程的线程池,但希望每个线程专用于单一类型的任务。即任务1只能在池的线程1上执行,池2的线程2上的任务2。我不想要两个以上的线程,我不希望两个task1(s)同时运行(每个线程一个)。可能??

3 个答案:

答案 0 :(得分:2)

不,不可能。这是使用线程池的好处:池将选择执行传递任务的线程。请注意,即使您使用Executors#newFixedThreadPool(2),也会有一个包含2个线程的线程池,但这并不能保证每个任务都在不同的线程中执行。

如果您需要在不同的特定线程中执行任务,请改为创建自己的线程。如果您不想手动创建线程,请使用2个单线程执行程序。您可以使用Executors#newSingleThreadExecutor创建它们(但这非常麻烦)。

答案 1 :(得分:0)

虽然已经接受了答案,但您必须使用AtomicBoolean代替volatile。 喜欢

AtomicBoolean task1RunningAB = new AtomicBoolean( false);

Runnable task1 = () -> {
    // compareAndSet( E, N) sets the value to N if current value matches E. 
    // Returns true if that was the case, so we must negate here
    if ( ! task1RunningAB.compareAndSet( false, true))
         return; 
    try {
        // your code
    } finally {
        task1RunningAB.set( false);
    }
};

答案 2 :(得分:-1)

如果您想确保单个任务不会同时执行两次,请使用boolean指定该任务是否正在运行:

(Java 8 +)

volatile boolean task1Running = false;

Runnable task1 = () -> {
     if(task1Running)
          return; //already running, exit

     task1Running = true;
     //handle task
     task1Running = false;
};

现在当你尝试在它已经运行时执行它时,它会退出。 volatile是为了确保当我们从管理任务的线程更改task1Running时,所有其他线程(特别是执行任务的线程)将立即看到它。