2012-01-03 18 views
3

私は信号機システムをシミュレートするつもりです。 JFrameを拡張してRunnableを実装するRoadクラスを作成しました。Javaの実行可能オブジェクトの変数にアクセスする方法

run()メソッドの中で、私はそれぞれの車のY位置を増加させるロジックを追加しました。そして、現在、車の動きをシミュレートしています。 しかし、私は車を移動する前に、トラフィックライトの状態を確認する必要があります。

これは

import java.util.Random; 

public class TrafficLight implements Runnable { 

volatile boolean stop; 

public TrafficLight(boolean stop) { 
    this.stop = stop; 
} 

@Override 
public void run() { 
    Random randomGenerator = new Random(); 
    while (true) { 
     if (stop) { 
      stop = false; //change current status 
     } else { 
      stop = true; //change current status 
     } 
     try { 
      Thread.sleep(2000 + randomGenerator.nextInt(2000)); 
     } catch (Exception ex) { 
      System.out.println("error"); 
     } 
     } 
    } 
} 

は私の道クラスから、この揮発性変数停止をチェックする方法はあり、私のTrafficLightクラスです。

もしそうでない場合は、これを行う別の解決策を提案してください。

ありがとうございました。

+0

ストップ変数へのアクセスを得るためにそれを使用するには、この宿題ですか?もしそうなら、あなたは '宿題 'タグを追加すべきですか? – helios

+2

'while(true)...'ブロックで 'InterruptedException'(これはcatchブロックで何をするのか)を呑み込むのは悪い考えです。アプリケーションが正常にシャットダウンするのは難しいでしょう。終了する。あなたがそれを処理したくなければ 'RuntimeException'としてそれを再現する方がよいでしょう。 – artbristol

答えて

6

停止のためのアクセサを実装します。

public class TrafficLight implements Runnable { 

    volatile boolean stop; 

    // Irrelevant code 

    public boolean isStop() { 
    return stop; 
    } 
} 

RoadクラスのコンストラクタにTrafficLightを受信し、

public class Road implements Runnable { 

    private TrafficLight trafficLight; 

    public Road (TrafficLight trafficLight) { 
    this.trafficLight = trafficLight;  
    } 

    @Override 
    public void run() { 
    // Irrelevant code 
    if(trafficLight.isStop()) { 
     // do something 
    } 
    } 
} 
+0

ありがとうございます@Anthony。私はあなたの助けを借りて問題を解決しました。 –

0

これは、車が交通信号の変化を聞く必要があるということですか?オブザーバーのデザインパターンもここで役立ちます。

1

Road(または値を必要とする人)は、TrafficLightのインスタンスにアクセスし、緑色であればそれを尋ねる必要があります。ブールメソッドを提供することができます。

しかし、このプロパティ(停止)へのアクセスは守られなければなりません。 volatileキーワードはあまり役に立ちません(下記参照)。ほかのオブジェクトがライトの変化に反応する必要がある場合、(「光が変更された」イベントに反応する)

private synchronized void toogleStopped() { // guarded 
    this.stop = !this.stop; 

} 

public synchronized boolean isStopped() { // guarded 
    return this.stop; 
} 

イベント

オブザーバーデザインパターンを使用します。

私のような何かを行う必要があります@TejasArjunが提案したように。

なぜvolatile

volatileは、Javaは変数は、 "外部から" に変更されていないと仮定しないようにする助けにはなりません。したがって、スレッドがその値を設定する(または前に読み込む)場合、2番目の読み込みではキャッシュされた値(おそらくCPUレジスタなどに保存されている値)が使用されます。 volatileはJavaが常にメモリから値を読み込むようにします。

紛失した更新の問題は、キーワードvolatileであっても残ります。 1つのスレッドは、1)2)の書き込みを読み取ることができます。別のスレッドでも同じことができます。そして、彼らはこの順序でそれを行うことができます。

スレッド1が偽 スレッド2は、(それが偽読むと仮定した場合) スレッド2組の真(それが偽読むと仮定)真偽 スレッド1セットを読み込み、読み込ん

そして、それはです素敵ではありません:)

したがって、Javaにread &をアトミックに書き込ませる必要があります。そのため、​​キーワードを使用して、スレッドがsync'edブロック全体を一度に処理し、別のスレッドとインターレースしないようにすることができます。

+2

また、heliosのようにアトミックに読み込み/更新を行う必要がある場合は、別のオプションとして[AtomicBoolean](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/)を使用します。 atomic/AtomicBoolean.html)。 'TraffigLight'だけが値を止める場合には、どちらも必要ありません。 –

関連する問題