当前位置: 首页 > 知识库问答 >
问题:

定期通知多个线程

李星辰
2023-03-14

我正在做一个项目,它使用原始Java并发结构,如等待()、通知()、通知()、Thread.run()、html" target="_blank">同步化等。在我的项目中,有多个线程(线程类的扩展)会定期从队列中获取一个对象。因此,我使用了一个有内部TimerWork类的Timer类。

我的问题是,我无法获得如何让其他线程定期唤醒。我的主要类不是这些线程或计时器类。因此,我从另一个类调用它们的运行。我不知道如何让这些线程每100毫秒等待和通知一次。我的计时器类是:

public class Controller extends Timer{

    int counter;
    TimerTask task;
    final Controller c = this;

    public class PeriodicTime extends TimerTask {

        @Override
        public void run() {

            if(counter > 0) {
                //do some stuff to wake up threads

            }
            counter++;
        }
    }

    Controller () {
        super ();
        this.task = new PeriodicTime();
        counter = 0;
        this.schedule(task, 300, 100);
    } 
}

我的线程类是:

public class Element extends Thread {


    public void run() {

        // do something to get an object from another class (a queue)
    }
}

现在,我真的很困惑如何对线程类进行周期性释放。我甚至不知道是否使用等待()/通知()。

正如我之前所说的,我将创建多个元素类。他们将同步工作。然后,我该怎么办?

共有1个答案

孙星鹏
2023-03-14

创建一个表示互斥体的对象列表,每个元素线程将从列表中获取一个互斥体,而计时器任务将获取列表。

当时间段过期时,TimerTask对每个互斥对象调用notify()。这会唤醒元素线程。

元素线程处理队列中的数据,完成后,每个线程都对互斥对象调用wait()。

现在,您需要在队列中内置线程安全性,因为有多个使用者,而不是阻塞逻辑,因为它是由TimerTask处理的。

此外,如果我理解正确的话,你希望元素在处理数据时把一些东西放回队列。为此,你可以使用一个辅助队列,在元素完成后,你可以把它排入第一个队列,或者你可以交换它们(这是由时间任务完成的,需要一个原子计数器,当元素醒来时它会递增,当它进入睡眠时它会递减)。或者,你可以使用一个“停止”值,你可以在唤醒元素之前把它放入队列,让它们一直工作到到达它。对于N个元素线程,你需要输入N个停止值,这样它们都能得到消息。

如何使用互斥锁:

List<Object> mutexList;
//initialize the list with plain Objects. You just need them to be separate instances.
....
//When creating Element threads add one object from the list to each Element.
....
//in Element code
public class Element extends Thread {
   //This is one element from the list 
   private Object mutex;


    public void run() {
       // do something to get an object from another class (a queue)
       //....
       synchronized(mutex){ 
          mutex.wait();
       }
    }
}
// in timerTask code
 public class PeriodicTime extends TimerTask {

    List<Object> mutexList;

    @Override
    public void run() {

        if(counter > 0) {
            //do some stuff to wake up threads
           for(Object mutex:mutexList){
                mutex.notify();
           }
        }
        counter++;
    }
}
 类似资料:
  • 问题内容: 我试图在我的应用程序中创建多个通知。为了唯一地标识每个通知,我给了它们一个唯一的identificationId。以下是我的代码: 问题:选择通知后,将调用Tabs活动来传递意图。我想访问在“选项卡”中选择的通知的唯一notificationId。我尝试了intent.putExtra()来将NotificationId保存在intent中。但是,对于多个通知,它会覆盖notifyId

  • 代码: 结果: 代码在jdk1.7和jdk1.8中执行相同的结果。 我的问题: > 线程 A 和线程 B 进入 SYNCHRONIZED 块并调用 wait() 方法后,为什么线程 C 和线程 D 进入而不是线程 A 说 i,然后线程 B 说 i?输入同步块的优先级是否高于刚刚调用 wait() 方法的线程? 为什么调用通知()方法只是唤醒调用等待()方法的最后一个线程?就像线程C和线程D一样,相

  • 我有一段代码 如您所见,我首先将标志设置为false,这样其中一个线程就可以进入Sum2Elements方法并将其更改为true,从而让所有人都等待。 我知道在同步代码中,只有一个线程可以完成它的任务,这里我有两个同步方法,这是否意味着两个线程在每次通知之后都在尝试执行这个方法? 如果是这样,那么一个线程是否不可能输入Sum2Elements,在另一个线程进入InsertElement之前将标志更

  • 我对通知方法的一点感到困惑。“notify() :它唤醒一个在同一对象上调用 wait() 的线程。因此,假设两个线程称为等待同一对象。那么当我调用通知时,将通知哪个线程?

  • Redisson的看门狗实现中,对于续期失败的异常处理就是释放锁: 见红框 也就是说主线程不会知道当前锁是否还有效,可能锁因为续期失败已经过期了,但主线程还在处理业务。 这种情况应该怎么处理呢?

  • 问题内容: 想象一下,您在Java中有一个典型的生产者- 消费者模式。为了提高效率,您要使用而不是在将新元素添加到队列时使用。如果两个生产者线程调用notify,是否保证将唤醒两个不同的正在等待的使用者线程?还是彼此之间很快触发的两个s导致同一用户线程排队两次唤醒?我找不到该部分描述此工作原理的API。Java是否有一些原子内部操作可仅一次唤醒线程? 如果仅一个消费者正在等待,则第二个通知将丢失,