定期通知多个线程

时间:2014-12-26 13:44:55

标签: java multithreading timer timertask periodic-task

我正在开发一个使用原始Java并发结构的项目,例如wait(),notify(),notifyAll(),Thread.run(),synhronized等。 在我的项目中,有多个线程(Thread类的扩展)将定期从队列中获取对象。因此,我使用Timer类,它具有内部TimerTask类。

我的问题是,我无法得到如何使其他线程定期唤醒。我的主要类不是这些线程或计时器类。因此,我从另一个班级打电话给他们。我无法弄清楚如何使这些线程等待并通知每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)
    }
}

现在,我真的很困惑如何定期发布线程类。我甚至无法得到是否使用wait()/ notify()。

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

1 个答案:

答案 0 :(得分:0)

列出将代表互斥锁的对象列表,每个元素线程将从列表中获取一个互斥锁,而计时器任务获取列表。

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

元素线程处理来自队列的数据,当它们完成时,它们每个都在它们的互斥对象上调用wait()。

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

此外,如果我理解正确,您希望Elements在处理数据时将某些东西放回队列。为此,你可以使用一个辅助队列,你可以在元素完成之后将其排入第一个队列,或者你可以只交换它们(这是由TimerTask完成的,需要一个原子计数器,当元素唤醒时它会增加,当它进入时会递减睡觉)。或者,您可以使用" stop"在唤醒Elements之前可以放入队列的值,并使它们工作直到它们到达它。对于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++;
    }
}