繁体   English   中英

我如何使线程最后一次在通知时唤醒?

[英]How do I make a Thread wake up last on notify?

我有多个线程正在等待滴答时钟的notify()。 这些线程之一应在运行之前等待其余线程执行。 通常,我相信这样做的方法是使用join(),但是在这种情况下,线程永不消亡,它们只是等待下一个滴答信号。 有没有一种方法可以确保在收到相同的notify()之后,线程“ z”将始终在线程“ ay”之后唤醒?

编辑:例如添加代码

线程1-4:

while(running) {
    synchronized(tickSignal){
        /*
         * Code in this section adds objects to a queue that Thread 5 reads
         * It also has other code that must be executed every tick
         */
        tickSignal.wait();
    }
}

线程5:

while(running) {
    synchronized(tickSignal) {
        /*
         * Code in this section reads all the objects added to the queue by T1-4
         * It also has other code that must be executed every tick
         */
        tickSignal.wait();
    }
}

刻度时钟:

while(running) { 
    synchronized(tickSignal){
        tickSignal.notifyAll();
    }
    Thread.sleep(1000);
}

还有其他监视tickSignal的线程根本不与线程5交互。

如果我正确理解,则在发出滴答信号时有N个任务要执行。 N个任务只能在第一个N-1个任务完成后开始。 由于notifyAll()函数以无序方式通知线程,因此您必须稍微扩展代码。

首先,我认为这种建筑不是安全的建筑。 考虑一下在一个线程中执行代码花费超过1秒的情况。 在这种情况下,由于线程尚未到达wait()函数,因此不会在下一个滴答信号处通知该线程。 但是,现在让我们假设这不会发生。

由于第N个任务只能在第一个N-1个任务完成后才能执行,因此它必须等待并在第一个N-1个任务实际完成时得到通知。 为了计算已完成任务的数量,可以使用线程安全的AtomicInteger计数器。 每次任务完成时,计数器都会以1递增。当计数器达到值N-1时 ,它会通知第N个线程并将该值重置为0。

为您提供代码:

// Besides a tickSignal, we also need a finalThreadSignal, which 
// will be notified when the first N-1 Threads are finished.
private Object tickSignal = new Object();
private Object finalThreadSignal = new Object();
private AtomicInteger completedThreadsCounter = new AtomicInteger(0);

线程1-(N-1):

while (running) {
    synchronized (tickSignal) {
        try {
           tickSignal.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // Code

        // Task finished
        int counter = completedThreadsCounter.incrementAndGet();
        if (counter == N-1) {
            // Notify Thread N when the first N-1 tasks are finished
            synchronized (finalThreadSignal) {
                finalThreadSignal.notify();
            }
            // Reset the finished Threads counter and wait for the next tick signal
            completedThreadsCounter.set(0);
        }
    }
}

线程N:

while (running) {
    // Here we synchronize on the signal that will be given when 
    // the first N-1 Threads are finished
    synchronized (finalThreadSignal) {
        try {
            finalThreadSignal.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // Execute final Thread code
    }
}

正如我已经指出的,如果一个线程中的执行时间大于两次滴答之间的时间,则这种构造将失败。 请让我确切知道问题所在,以便为您提供更合适的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM