给定线程id,在特定线程上运行方法

时间:2016-09-22 08:21:21

标签: java multithreading concurrency

如果我知道特定的线程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();


}
}

2 个答案:

答案 0 :(得分:1)

您需要使用锁定来阻止线程,然后调用lock的notify方法来设置阻塞的线程可运行。
如果要继续多个帖子,则需要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();

答案 1 :(得分: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) {
    }

  }  
}