2013-11-26 2 views
0

Я пытаюсь решить проблему Философа, используя Future на Java.«Обеденные философы» с использованием Fututre в Java

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 завершается выполнение, она возвращает тот же результат.

Теперь я сомневаюсь, что решить эту проблему с будущим возможно не удастся?

Не мог бы кто-нибудь пролить свет на это.

+0

Я думаю, что ошибка в той части, где вы действительно используете Callable. Можете ли вы отправить эту часть кода? – TwoThe

+1

Жизненный цикл вызываемого пользователя до тех пор, пока он не вернет результат, тогда как жизненный цикл алгоритма намного больше. Философ не должен заканчивать исполнение, возвращая статус. –

+0

@TwoThe добавил код. – nish1013

ответ

1
class Philo implements Runnable{ 

    @Override 
    public void run(){ 
     while(true){ 

      if(Thread.interrupted()){ 
       break; 
      } 

      //dining logic 
     } 

    } 
} 

Решение может быть петля, которая выполняет пока кто-нибудь прерывает Philosopher.

+0

Спасибо. Но тогда это решение становится независимым от Future, хотя :( – nish1013

+1

Да, проблема не имеет возвращаемого значения, но является долговременной задачей, которая по умолчанию не соответствует Future. –

+0

Я вас слышу. Поэтому Future - не подходящая конструкция для этой проблемы. – nish1013

1

A 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 Философ» фактически описывает, что проблема нитей в состоянии сделать что-то в любое время, так как в этом случае вы отделили столовые попытки, которые, скорее всего, все время преуспевают.

Если вы хотите, чтобы эти потоки фактически блокировались, вам нужно дать им возможность параллельно работать , что означает, что Callable - это не правильный способ имитации этой проблемы. Тем не менее, ваша попытка имеет ценный урок, который нужно изучить: если вам удастся разместить свою работу в отдельных партиях, как описано выше, потоки гораздо реже блокируются. И вот почему Исполнитель был изобретен в первую очередь.

Смежные вопросы