如何从BlockingQueue获取对象?

时间:2015-05-15 08:42:47

标签: java multithreading

我有一个班级X,班级Machine,班级Z,所有这些都是主题。初始化Machine个线程时,会将它们放在BlockingQueue firstQueue上。内部机器' run方法有一个while循环,它检查它的布尔变量是真还是假。如果是,则应将机器放在BlockingQueue secondQueue

secondQueue.put(this);

Z类可以从那里获取它。如果机器线程返回false,则类X可以从firstQueue获取机器并对其进行处理。 现在,我的问题是:当布尔值为真时,是否可以让MachinefirstQueue中获取? PS。我知道问题可能不明确,但我不知道如何正确地形成它。如果有人知道要做得更好,请更正。

EDIT。 代码示例。 这是从类开始所有线程的一部分,当然所有队列都被初始化。

public class Machine implements Runnable{
private final BlockingQueue firstQueue;
private final BlockingQueue secondQueue;
boolean broken;

public Machine(...){...}


 public void run() {

    while(true){
            //use Rand (min=0, max=1) and define if(random==1)broken=true else broken=false

            if(broken==true){
                Machine multi = fistQueue.take(this);//here is problem!!!!!
                secondQueue.put(this);
            }  
     }
}...}

和启动线程的部分表单类

//machines should have an ability to take themselves from queue when broken==true, and then put on secondQueue
BlockingQueue<Machine> firstQueue = new ArrayBlockingQueue<Machine>(10);
    service=Executors.newFixedThreadPool(10);
    for(int k=0; k < 10; k++){
        Machine M= new Machine(secondQueue, k);
        firstQueue.add(M);
        service.submit(M);
    }

 //X can take machines from firstQueue, and work on them if broken==false
Thread XThread = new Thread(new X(firstQueue));
    XThread.start();

//takes machines form secondQueue
    Thread ZThread = new Thread(new Z(secondQueue));
    ZThread.start();

EDIT2

public class X implements Runnable(){

//fields, constructor

public void run() {

    while(true){
            machine=machines.take();
            if(machine.broken==true){
                //leave this machine (it should be on , and take other which is fine_
            } 
            while(machine.broken==false){
                machine.pass(record); // (Record record=new Record(task, result field);
               //do Your thing
           }
           if(result==initialResultFromX){
              //means it got broken while working and needs to take a new machine
             }
}...
}

1 个答案:

答案 0 :(得分:1)

首先,这个答案旨在帮助改进解决方案的设计,而这又可以回答实际问题。但是,如果OP对当前的设计感到满意,我相信可以通过删除以下行来回答这个问题:

Machine multi = fistQueue.take(this);

所以,

  

是否可以让机器从firstQueue中获取自己?

没有方法可以直接获取队列中的对象而不删除它(如注释中所述,不应该从第一个队列中删除该机器)。因为您可以使用this访问计算机实例,所以secondQueue.put(this)就足以将Machine添加到第二个队列。

我可能会错误地解释你的设计,但在我看来,每个Machine都有一个状态。此状态取决于Machine是否可以执行必须执行的任何操作。如果这是真的,我认为保持机器本身状态变化的处理是不明智的(将其自身添加/移除到不同的执行队列)。

你需要某种抽象。让我们称之为StateMachineStateMachine通过实现一些监听接口来创建,管理和处理每个Machine的状态更改。这将允许每台计算机向StateMachine报告任何事件或问题。然后StateMachine可以确定如何处理事件。

我会试着通过例子来解释。以下是StateMachine将实现的界面:

public interface BrokenListener {
    public void onBrokenEvent(Object machine);
}

这允许StateMachine和每个Machine之间的通信。但是,这需要将StateMachine的实例传递给每台计算机而不是队列。

for(int k=0; k < 10; k++){
    Machine m = new Machine(this); //where this is the StateMachine
    firstQueue.add(m);
}

Machines状态从broken == false更改为broken == true后,可以调用onBrokenEvent()

public class Machine {
    /* The listener */
    private BrokenListener listener;
    private boolean broken = false;

    public Machine(BrokenListener listener) {
        this.listener = listener;
    }

    /* When the state of the machine changes */
    public void setBroken(boolean broken) {
        this.broken = broken;
        if (this.broken) {
            //Here we pass the current Machine to the StateMachine. How the event is handled should not be up to the machine.
            this.listener.onBrokenEvent(this);                
        }
    }
}

以下是StateMachine

public class StateMachine implements BrokenListener {
    @Override
    public void onBrokenEvent(Object machine) {
        if (machine instanceof Machine) {
            second.add((Machine) machine);
        }
    }
}

正如您所看到的,当状态机实现onBrokenEvent方法时。当Machine调用此方法时,可以将其添加到第二个队列进行处理。

我假设XY类将进行处理,因此您仍然需要将队列传递给它们。

Thread XThread = new Thread(new X(firstQueue));
XThread.start();

Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();

这样做的好处是,它保留了用于处理状态变化的逻辑Machine

随时提出任何问题。