2016-12-15 5 views
-1

私は以下の問題を解決するプログラムを書いていますが、私はSTARVATIONを無料でしようとしていますが、実装方法はわかりません。だから、北の農家と南の農家はそれぞれ、橋を渡る機会が同じになる。Javaでスレッドの飢餓を防ぐ方法

シナリオ シングルレーンブリッジは、北と南タンタンブリッジの2つのバーモント州の村を接続しています。 2つの村の農民は、この橋を使って農産物を近隣の町に届けます。北行きと南の農家の両方が同時に橋の上を取得する場合ブリッジはデッドロックになることができ、私が試したものをここで

(バーモント州の農家が頑固で、バックアップすることはできません。):

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順に実行されます。

ドキュメントは、フラグの使用上の注意事項があります。

一般

、リソースへのアクセスを制御するために使用するセマフォが何のスレッドがリソースにアクセスするから餓死されていないことを保証するために、公正に初期化されなければなりません。他の種類の同期制御にセマフォを使用する場合、公正でない順序付けのスループットの利点は、しばしば公正さの考慮よりも重要です。

関連する問題