如何让特定线程成为下一个进入同步块的线程?

Vin*_*C M 12 java multithreading

我在接受采访时被问到这个问题.

有四个线程t1,t2,t3和t4.t1正在执行同步块,其他线程正在等待t1完成.你会做什么操作,以便在t1之后执行t3.

我回答说join方法应该可以解决问题,但看起来它不是正确的答案.他给出的原因是,join方法和setPriority方法不适用于处于等待状态的线程.

我们能做到吗?如果有,怎么样?

Vic*_*kin 5

您可以使用锁和条件.将相同的条件传递给t1和t3:

class Junk {

   private static class SequencedRunnable implements Runnable {
       private final String name;
       private final Lock sync;
       private final Condition toWaitFor;
       private final Condition toSignalOn;

       public SequencedRunnable(String name, Lock sync, Condition toWaitFor, Condition toSignalOn) {
           this.toWaitFor = toWaitFor;
           this.toSignalOn = toSignalOn;
           this.name = name;
           this.sync = sync;
       }

       public void run() {
           sync.lock();
           try {
               if (toWaitFor != null)
                   try {
                       System.out.println(name +": waiting for event");
                       toWaitFor.await();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               System.out.println(name + ": doing useful stuff...");
               if (toSignalOn != null)
                   toSignalOn.signalAll();
           } finally {
               sync.unlock();
           }
       }
   }

   public static void main(String[] args) {
       Lock l = new ReentrantLock();
       Condition start = l.newCondition();
       Condition t3AfterT1 = l.newCondition();
       Condition allOthers = l.newCondition();
       Thread t1 = new Thread(new SequencedRunnable("t1", l, start, t3AfterT1));
       Thread t2 = new Thread(new SequencedRunnable("t2", l, allOthers, allOthers));
       Thread t3 = new Thread(new SequencedRunnable("t3", l, t3AfterT1, allOthers));
       Thread t4 = new Thread(new SequencedRunnable("t4", l, allOthers, allOthers));

       t1.start();
       t2.start();
       t3.start();
       t4.start();

       l.lock();
       try {
           start.signalAll();
       } finally {
           l.unlock();
       }
   }
}
Run Code Online (Sandbox Code Playgroud)


M P*_*oet 5

每个线程应该简单地在一个单独的对象上 wait()。所以 t3 应该等待 t3Mutex。然后您可以简单地通知该特定线程。

final Object t1Mutex = new Object();
final Object t3Mutex = new Object();
...
synchronized(t3Mutex) {
    //let thread3 sleep
    while(condition) t3Mutex.wait();
}
...
synchronized(t1Mutex) {
   //do work, thread1
   synchronized(t3Mutex) {t3Mutex.notify();}
}
Run Code Online (Sandbox Code Playgroud)


ext*_*eon 4

我想我会使用一些闩锁。t1 和 t2 之间有一个倒计时锁存器,t2 和 t3 之间有另一个倒计时锁存器,t3 和 t4 之间有最后一个倒计时锁存器。T1以倒计时结束,t2以await开始待同步部分。

这样,所有线程都可以并行进行预处理并恢复顺序部分的顺序。

但我不能说它很优雅。