我正试图用Java解决使用Future的哲学问题。
public class Philo implements Callable<PhiloStatus> {
private PhiloStatus status;
private Philo leftPhilo;
private Philo rightPhilo;
private String name;
public Philo(String name) {
status = PhiloStatus.THINKING;
this.name =name;
}
public void setLeftPhilo(Philo leftPhilo) {
this.leftPhilo = leftPhilo;
}
enter code here
public void setRightPhilo(Philo rightPhilo) {
this.rightPhilo = rightPhilo;
}
@Override
public PhiloStatus call() throws Exception {
if (leftPhilo.getStatus() == PhiloStatus.THINKING
&& rightPhilo.getStatus() == PhiloStatus.THINKING) {
this.status =PhiloStatus.DINING;
System.out.println("Dininig "+this);
return PhiloStatus.DINING;
}
this.status =PhiloStatus.THINKING;
System.out.println("Thinking "+this);
return PhiloStatus.THINKING;
}
public PhiloStatus getStatus() {
return status;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name;
}
}
该计划的起点
public class Start {
/**
* @param args
*/
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
Philo[] philosophers = new Philo[5];
for (int i = 0; i < 5; ++i)
philosophers[i] = new Philo(""+i);
for (int i = 0; i < 5; ++i) {
philosophers[i].setLeftPhilo(philosophers[(i + 4) % 5]);
philosophers[i].setRightPhilo(philosophers[(i + 1) % 5]);
executorService.submit( philosophers[i]);
}
}
}
但似乎一旦Callable完成执行,它就会返回相同的结果。
我现在怀疑使用Future可能无法解决这个问题?
任何人都可以对此有所了解。
答案 0 :(得分:1)
class Philo implements Runnable{
@Override
public void run(){
while(true){
if(Thread.interrupted()){
break;
}
//dining logic
}
}
}
解决方案可以是循环,执行直到某人中断Philosopher
。
答案 1 :(得分:1)
Callable计算结果一次,然后返回此计算的值 。因此,如果您想再次计算某些内容,则需要再次运行Callable。
void diningAttempt() {
Future<PhiloStatus>[] results = new Future<PhiloStatus>[philosophers.length];
for (int i = 0; i < philosophers.length; ++i) {
results[i] = executor.submit(philosophers[i]);
}
for (int i = 0; i < philosophers.length; ++i) {
System.out.println(results[i].get());
}
}
然后在其他地方:
while (dining) {
diningAttempt();
}
正如您可能看到的,这与“Dining Philosopher”问题实际描述的内容略有不同,这就是线程能够随时做某事的问题,就像在这种情况下一样你有分开的用餐尝试,然后很可能一直成功。
如果您希望这些线程实际锁定,您需要让它们能够一直并行运行,这意味着Callable不是模拟此问题的正确方法。然而,您的尝试有一个值得学习的宝贵经验:如果您设法将您的工作分成不同的批次,那么线程就不太可能锁定。这就是Executor首先被发明的原因。