我有一个X
类,Machine
类,Z
类,它们都是线程。初始化Machine
线程后,将它们放在BlockingQueue firstQueue
上。在机器的运行方法中,有一个while循环,用于检查其 boolean 变量应为true还是false。正确时,应将机器放在BlockingQueue secondQueue
上
secondQueue.put(this);
Z
类可以从那里获取它。如果机器线程返回false,则X
类可以从firstQueue
中取出机器并对其进行处理。现在,我的问题是:当boolean为true时,是否有可能使
Machine
脱离firstQueue
?附言:我知道可能不清楚这个问题,但是我不知道如何正确地解决这个问题。如果有人知道可以做得更好,请更正它。
编辑。
代码样本。
这是类的一部分,它启动所有线程,所有队列当然都已初始化。
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();
编辑2
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
}
}...
}
最佳答案
首先,该答案旨在帮助改进解决方案的设计,从而可以回答实际问题。但是,如果OP对当前设计感到满意,我相信可以通过删除以下行来回答这个问题:
Machine multi = fistQueue.take(this);
所以,
没有一种方法可以直接获取队列中的对象而不将其删除(如注释中所述,不应从第一个队列中删除计算机)。因为您可以使用
this
访问该计算机的实例,所以secondQueue.put(this)
足以将Machine
添加到第二个队列中。我可能会误解您的设计,但是在我看来,每个
Machine
都有一个状态。此状态取决于Machine
是否可以执行必须执行的任何内容。如果这是真的,我认为将状态更改的处理保留在机器本身中(将自身添加/删除到不同的执行队列中)是不明智的。您需要某种抽象。让我们将其称为
StateMachine
。 StateMachine
通过实现一些监听接口(interface)来创建,管理和处理每个Machine
的状态更改。这将允许每台机器将任何事件或问题报告给StateMachine
。然后StateMachine
可以确定如何处理事件。我将以身作则。这是
StateMachine
将实现的接口(interface):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
调用此方法时,可以将其添加到第二个队列进行处理。我假设
X
和Y
类将进行处理,因此您仍然需要将队列传递给它们。Thread XThread = new Thread(new X(firstQueue));
XThread.start();
Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();
令其如此出色的是,它将用于处理状态更改的逻辑保持在
Machine
之外。随意问任何问题。