2016-09-22 15 views
0

特定のスレッドIDを知っている場合。次のようにするには?スレッドIDを指定して特定のスレッドでメソッドを実行

スレッド。 getThreadById(id).continueWork();

それは可能ですか?

public class Test implements Runnable { 

public void run() { 
    while(true){ 
    pause(); 

    doSomework(); 
    } 
} 

private void doSomework() { 
    System.out.println("do some work"); 
} 

public synchronized void pause() { 
    if (Tester.waitCondition == true) { 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public synchronized void continueWork() { 
    notify(); 
} 
} 

public class Tester { 

public static boolean waitCondition = true; 

public static void main(String[] args) { 
    Thread nThread = new Thread(new Test()); 
    nThread.start(); 
    waitCondition = false; 
    Thread nThread1 = new Thread(new Test()); 
    nThread1.start(); 
    Thread nThread2 = new Thread(new Test()); 
    nThread2.start(); 
    Thread nThread3 = new Thread(new Test()); 
    nThread3.start(); 

    Long id = nThread.getId(); 
    Thread.getThreadById(id).continueWork(); 


} 
} 
+0

いいえ、ありませんこの方法。異なるwaitConditionを用意する必要があります。それぞれのスレッドは独自のwaitConditionを持っています。 –

+0

詳しいことを教えてください。 –

+0

私はそれが不可能であることを知っています。しかし、私はこれを行う方法が欲しい –

答えて

0

エラボレーション:

public class Tester { 
    // Apologies, I'm too lazy to create two separate files 
    static public class Test implements Runnable { 

    private void doSomework() { 
     System.out.print(
      "do some work on Thread: " 
     +Thread.currentThread().getId() 
    ); 
     try { 
     Thread.sleep(500); // just to simulate a load 
     } 
     catch(InterruptedException e) { 
     // ignore 
     } 
    } 

    public void run() { 
     do { 
     boolean shouldIWait=true; 
     synchronized(Tester.lockingObj) { 
      Boolean flag=Tester.waitConditions.get(Thread.currentThread().getId()); 
      if(null!=flag) { 
      shouldIWait=flag.booleanValue(); 
      } // if null, the tester started me before creating my flag. I'll wait 
      if(shouldIWait) { 
      // I need to wait for someone to wake me 
      try { 
       Tester.lockingObj.wait(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
       // well, I'm interrupted, so I'll do no more work. 
       break; 
      } 
      } 
     } 
     if(false==shouldIWait) { 
      // waiting no more 
      this.doSomework(); 
     } 
     } while(true); 
    } 

    } 

    public static Object lockingObj=new Object(); 

    public static TreeMap<Long, Boolean> waitConditions= 
     new TreeMap<Long, Boolean>(); 

    public static void main(String[] args) { 
    Thread nThread = new Thread(new Test()); 
    Thread nThread1 = new Thread(new Test()); 
    Thread nThread2 = new Thread(new Test()); 
    Thread nThread3 = new Thread(new Test()); 

    // when starting, all threads will be waiting 
    waitConditions.put(nThread.getId(), true); 
    waitConditions.put(nThread.getId(), true); 
    waitConditions.put(nThread.getId(), true); 
    waitConditions.put(nThread.getId(), true); 

    nThread2.start(); 
    nThread1.start(); 
    nThread.start(); 
    nThread3.start(); 

    Long id = nThread.getId(); 
    synchronized (lockingObj) { // when notified, all thread should wakeup 
     waitConditions.put(id, false); // but only nThread will be allowed to doSomeWork 
     lockingObj.notifyAll(); // wake up all the threads. 
           // Those not allowed, will go into 
           // back waiting 
    } 

    try { 
     // just to have the main thread still running for a while 
     Thread.sleep(3000); 
    } catch (InterruptedException e) { 
    } 
    // maybe we want to switch of nThread and start another? 
    synchronized (lockingObj) { 
     waitConditions.put(id, true); 
     waitConditions.put(nThread1.getId(), false); 
     lockingObj.notifyAll(); 
    } 
    try { 
     // just to have the main thread still running for a while 
     Thread.sleep(3000); 
    } catch (InterruptedException e) { 
    } 

    } 
} 
+0

これは良いアイデアです。しかし、「//通知されたら、nThreadが起動するはずです」と言いましたが、実際には正しく開始しませんか? ロックオブジェクトの通知後にのみ開始されます。 –

+0

@AsiriLiyanaArachchi - それはwaitConditionsでそのエントリを調べ、doSomeWorkに許可されていない場合、待機状態に戻ります。 –

+0

私はあなたのロジックから理解していることは、各スレッドが開始時に待機位置にあることです。そして、waitingConditionをfalseに設定すると、何の制約もなくループされる準備ができて、lockObjectに対して通知されると、waitCondition falseを行ったスレッドが引き続き実行されます。他のスレッドも1回実行され、再び待機状態になることがあります。 –

1

ロックでスレッドをブロックし、ロックの通知メソッドを呼び出してブロックされたスレッドの実行可能を設定する必要があります。
継続するスレッドが複数ある場合は、Conditionが必要です。ブローのように

final Lock lock = new ReentrantLock(); 

final Condition condition1 = lock.newCondition(); 
final Condition condition2 = lock.newCondition(); 

Thread t = new Thread() { 
    @Override 
    public void run() { 

    try { 
     lock.lock(); 
     condition1.await(); 
     System.out.println("end cdt1"); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     lock.unlock(); 
    } 
    } 
}; 

t.start(); 

Thread t1 = new Thread() { 
    @Override 
    public void run() { 

    try { 
     lock.lock(); 
     condition2.await(); 
     System.out.println("end cdt2"); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     lock.unlock(); 
    } 

    } 
}; 
t1.start(); 

Thread.sleep(1000); 

Thread tt = new Thread() { 
    @Override 
    public void run() { 
    try { 
     lock.lock(); 
     condition1.signal(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     lock.unlock(); 
    } 
    } 
}; 
tt.start(); 

Thread.sleep(2000); 

Thread tt1 = new Thread() { 
    @Override 
    public void run() { 
    try { 
     lock.lock(); 
     condition2.signal(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     lock.unlock(); 
    } 
    } 
}; 
tt1.start(); 
+0

あなたが見ることができるように、複数のスレッドがあります。ロックオブジェクトをスレッドに渡し、2つのスレッドがどのスレッドを継続すべきか、どのスレッドを一時停止状態にするかを知る方法を待っている場合 –

+0

@AsiriLiyanaArachchiもしそうなら、 'Condition'を使う必要があります。 – passion

関連する問題