2013-04-12 16 views
7

スレッドがスレッドExecutorServiceのプールで実行されているかどうかを確認するにはどうすればよいですか?ExecutorServiceスレッドプールでスレッドが実行されているかどうかを確認する方法

背景:
フラグが設定されている場合、スレッドプール内のスレッド間で同期を行いたいとします。 フラグが同期のためにtrueに設定されている場合は、他のスレッドが実行中かどうかを確認し、完了を待ってから同期スレッドを呼び出して他のスレッドがこのブロックスレッドが終了するまで待機する必要があります。

フラグが設定されていない場合、同期する必要はなく、スレッドを並行して実行できます。

ありがとうございます!

+1

あなたが/なぜあなたは何をやっているのと私たちにいくつかのコンテキストを与えることができます:

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

次に、スレッドでは、単に名前が接頭辞で始まるかどうかを確認しますか? –

+0

試みましたthread.isAlive()? – Ankit

+0

どういう意味ですか? _task_が実行されているかどうか'ExecutorService'には常に' Threads'が生きています。あなたが必要とするものを推測するのではなく、私たちがあなたを助けることができるように、あなたのコードを投稿してください。 –

答えて

5

Semaphoreを使用する必要があります。

これにより、多くの「許可」が働くことができます。一度に1つのタスクしか実行しない場合は、Semaphoreに1つの許可を設定します。そうでない場合は、プール内のThreadより大きな数の許可を持つSemaphoreがあります。あなたが一度に実行するように一つのタスクを必要とするときあなただけnewSingleThreadExecutor()を使用することができるよう

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出くわし整理することが可能かどうかを確認するために少し周りをつついた

EDIT

。スレッドは、スレッドExecutorServiceのプールで実行されている場合、私がチェックするにはどうすればよい

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

SingleThreadExecutorで同じ効果を得ますか? – Bhargav

+0

@Bhargavどのような影響がありますか? –

+0

あなたは知っています。与えられた時刻に1つのタスクしか実行されていないことを確認してください – Bhargav

3

要するに、あなたはしません。エグゼクティブはそのように使うつもりはありません。スレッドを手動で管理する場合は、Executorsなしで実行します。エグゼキュータを使用する場合は、考え方をThreadからRunnableに変更してください。 java.util.concurrentの同期またはいずれかの高レベルの抽象化を使用して、ランナブルまたはクラスとメソッドをスレッドセーフにします。

3

:これはすっきり解決策を示唆しますか?

これは実際にExecutorServiceスレッドプールのコンテキストでは意味をなさないものです。プールであなたのRunnable(またはCallable)クラスが実行されています。多分あなたが求めているのは、特定のジョブがプール内で実行されているかどうかを確認できるかどうかです。

run()(またはcall())メソッドの前面にある各ジョブは、​​オブジェクトをチェックし、必要に応じて待機または続行できます。また、複数のスレッドプールを持ち、ジョブをより小さな部分に分割して、同時に実行されるジョブの部分を制御できるようにすることもできます。

しかし、一般的に@ Raalfが​​指摘しているように、あなたがやっていることは、スレッドプールの全ポイントに対してです。スレッドプールの全体のポイントは、ジョブが非同期に実行されることです。多くの同期ポイントが必要な場合は、再設計する必要があります。

お客様の環境についてより詳しくご説明された場合、お客様の基礎となる質問に具体的に対処できる場合があります。

+0

誰でもダウンボートにフィードバックを加えたいですか? – Gray

3

スレッドがスレッドExecutorServiceのプールで実行されているかどうかを確認するにはどうすればよいですか?

あなただけのスレッドが特定ExecutorServiceで実行されているかどうかを知りたい場合は、あなたが特定のThreadFactoryExecutorServiceを作成し、それがそのような特別な名前としてスレッドにいくつかの特別なプロパティを添付することができます。

if (Thread.currentThread().getName().startsWith(EXECUTOR_THREADNAME_PREFIX)) { 
    // In executor. 
} else { 
    // Not in executor. 
} 
関連する問題