首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >怎么才能让线程最后一次醒来通知呢?

怎么才能让线程最后一次醒来通知呢?
EN

Stack Overflow用户
提问于 2018-12-03 18:33:54
回答 1查看 392关注 0票数 0

我有多个线程在等待来自滴答时钟的通知()。其中一个线程应该等待其余线程在运行之前执行。通常,我认为这样做的方法是使用join(),但是在这种情况下,线程永远不会死,它们只是等待()等待下一个滴答信号。是否有办法确保线程"z“在收到相同的通知()时总是在线程”a“之后醒来?

编辑:例如添加了代码

线程1-4:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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();
    }
}

滴答钟:

代码语言:javascript
复制
while(running) { 
    synchronized(tickSignal){
        tickSignal.notifyAll();
    }
    Thread.sleep(1000);
}

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-05 12:44:49

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

首先,我认为这个建筑是不安全的。考虑一下在线程中执行代码需要超过1秒的情况。在这种情况下,线程将不会在下一个滴答信号中得到通知,因为它还没有到达wait()函数。然而,让我们暂时假设这不会发生。

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

给你密码:

代码语言:javascript
复制
// 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):

代码语言:javascript
复制
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:

代码语言:javascript
复制
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
    }
}

正如我已经指出的,如果线程中的执行时间大于两个滴答之间的时间,则此构造将失败。请让我确切地知道问题是什么,给你更合适的答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53599776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档