我有一个班级X
,班级Machine
,班级Z
,所有这些都是主题。初始化Machine
个线程时,会将它们放在BlockingQueue firstQueue
上。内部机器' run方法有一个while循环,它检查它的布尔变量是真还是假。如果是,则应将机器放在BlockingQueue secondQueue
secondQueue.put(this);
和Z
类可以从那里获取它。如果机器线程返回false,则类X
可以从firstQueue
获取机器并对其进行处理。
现在,我的问题是:当布尔值为真时,是否可以让Machine
从firstQueue
中获取?
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
}
}...
}
答案 0 :(得分:1)
首先,这个答案旨在帮助改进解决方案的设计,而这又可以回答实际问题。但是,如果OP对当前的设计感到满意,我相信可以通过删除以下行来回答这个问题:
Machine multi = fistQueue.take(this);
所以,
是否可以让机器从firstQueue中获取自己?
没有方法可以直接获取队列中的对象而不删除它(如注释中所述,不应该从第一个队列中删除该机器)。因为您可以使用this
访问计算机实例,所以secondQueue.put(this)
就足以将Machine
添加到第二个队列。
我可能会错误地解释你的设计,但在我看来,每个Machine
都有一个状态。此状态取决于Machine
是否可以执行必须执行的任何操作。如果这是真的,我认为保持机器本身状态变化的处理是不明智的(将其自身添加/移除到不同的执行队列)。
你需要某种抽象。让我们称之为StateMachine
。 StateMachine
通过实现一些监听接口来创建,管理和处理每个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
调用此方法时,可以将其添加到第二个队列进行处理。
我假设X
和Y
类将进行处理,因此您仍然需要将队列传递给它们。
Thread XThread = new Thread(new X(firstQueue));
XThread.start();
Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();
这样做的好处是,它保留了用于处理状态变化的逻辑Machine
。
随时提出任何问题。