2016-12-15 2 views
-1

У меня есть Письменная программа, которая решает проблему ниже, но я пытаюсь сделать ее STARVATION FREE, но я не уверен, как ее реализовать. Таким образом, каждый северный фермер и южные фермеры получают равный шанс пересечь мост.Как предотвратить голодание в java

Сценарий однополосной мост соединяет два Vermont деревни Северной и Южной Танбриджа Танбриджа. Фермеры в двух деревнях используют этот мост для доставки своей продукции в соседний город. Мост может стать тупиковым, если одновременно на север и на юг фермер получить на мосте в то же время

Вот что я пытался (Вермонт фермеры упрямы и не в состоянии создать резервную копию.):

package threading.practice; 

import java.util.concurrent.Semaphore; 
import java.util.concurrent.TimeUnit; 

public class SingleLaneBridge { 

    public static void main(String[] args) 
    { 
     final Bridge bridge = new Bridge(); 

     Thread thNorthbound = new Thread(new Runnable() { 

      @Override 
      public void run() { 

       while(true) 
       { 
        Farmer farmer = new Farmer(bridge); 
        Thread th = new Thread(farmer); 
        farmer.setName("North Farmer : "+th.getId()); 
        th.start(); 
        try 
        { 
         TimeUnit.SECONDS.sleep((long)(Math.random()*10)); 
        } 
        catch(InterruptedException iex) 
        { 
         iex.printStackTrace(); 
        } 
       } 

      } 
     }); 

     Thread thSouthbound = new Thread(new Runnable() { 

      @Override 
      public void run() { 

       while(true) 
       { 
        Farmer farmer = new Farmer(bridge); 
        Thread th = new Thread(farmer); 
        farmer.setName("South Farmer : "+th.getId()); 
        th.start(); 
        try 
        { 
         TimeUnit.SECONDS.sleep((long)(Math.random()*10)); 
        } 
        catch(InterruptedException iex) 
        { 
         iex.printStackTrace(); 
        } 
       } 
      } 
     }); 

     thNorthbound.start(); 
     thSouthbound.start(); 
    } 

} 

class Bridge 
{ 
    private final Semaphore semaphore; 

    public Bridge() 
    { 
     semaphore = new Semaphore(1); 
    } 
    public void crossBridge(Farmer farmer) 
    { 
     try 
     { 
      System.out.printf("Farmer %s is trying to cross the bridge.\n",farmer.getName()); 
      semaphore.acquire(); 
      System.out.printf("Farmer %s is crossing the bridge.\n",farmer.getName()); 
      long duration = (long)(Math.random() * 10); 
      TimeUnit.SECONDS.sleep(duration); 
     } 
     catch(InterruptedException iex) 
     { 
      iex.printStackTrace(); 
     } 
     finally 
     { 
      System.out.printf("Farmer %s has crossed the bridge.\n",farmer.getName()); 
      semaphore.release(); 
     } 
    } 
} 

class Farmer implements Runnable 
{ 
    private String name; 
    private Bridge bridge; 

    public Farmer(Bridge bridge) 
    { 
     this.bridge = bridge; 
    } 

    public void run() 
    { 
     bridge.crossBridge(this); 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 
+0

Вам нужно будет предоставить более подробную информацию о том, как вы обнаруживаете голод и почему думаете, что это происходит. Вы перешли код в своем отладчике IDE? Что ты нашел? Кроме того, почему вы повторяете принципиально идентичный код для Севера и Юга? Разумеется, можно использовать один параметризованный «Runnable». –

ответ

0

java.util.concurrent.Semaphore имеет constructor that takes a fairness flag. Когда это установлено, очереди приобретают и гарантируют, что они выполняются в порядке fifo.

Док имеет записку об использовании флага:

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

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