2016-12-07 18 views
0

私は現在2レーンの空港アプリケーションで作業していますが、飛行機の着陸に問題があります。レーンが1つしかない場合はすべて動作しますが、レーンを追加すると、同時に両方のレーンに着陸する必要があります。私はSystem.outを使ってどこに問題があるのか​​見てみましたが、それはほとんど役に立ちませんでした。もしあなたが私が間違っていることを見てもらえるように助けることができたら、私はとても感謝しています。同期とマルチスレッド

パブリッククラス空港{

private List<Lane> lanesOpen = new ArrayList<Lane>(); 
private List<AirplaneThread> airplanes; 

public void start(){ 
    for(AirplaneThread airplane : airplanes){ 
     if(airplane.getState()==Thread.State.NEW) 
      airplane.start(); 
    } 
} 

public void open(List<AirplaneThread> airplanes) { 
    this.airplanes = airplanes; 
} 

public synchronized void requestLane(){ 
    while(getLanesAvailable().size()==0 && airplanes.size()==0){ 
     try { 
      wait(); 
     } catch (InterruptedException e) {  } 
    } 
    List<Lane> lanes = getLanesAvailable(); 
    for(Lane lane: lanes){ 
     if(airplanes.size()>0){ 
      AirplaneThread airplane = airplanes.remove(0); 
      airplane.land(lane); 
     } 
    } 
    notifyAll(); 
} 

public synchronized void landingIsOver(Lane lane){ 
    while(!lane.isClear()){ 
     try{ 
      wait(); 
     }catch(InterruptedException e){ 
     } 
    } 
    lane.getText().setText(""); 
    notifyAll(); 
} 

public List<Lane> getLanesAvailable(){ 
    List<Lane> lanes = new ArrayList<>(); 
    synchronized(lanesOpen){ 
    for(Lane l : lanesOpen){ 
     if(l.isClear()) 
      lanes.add(l); 
    } 
    } 
    return lanes; 
} 

public void addLaneOpen(Lane lane){ 
    synchronized(lanesOpen){ 
    lanesOpen.add(lane); 
    } 
} 

public void removeLane(Lane l){ 
    synchronized(lanesOpen){ 
    Iterator<Lane> iterator = lanesOpen.iterator(); 
    while(iterator.hasNext()){ 
     Lane lane = iterator.next(); 
     if(lane.getNumber()==l.getNumber()) 
      iterator.remove(); 
    } 
    } 
} 

AirplaneThreadは、スレッドがAirplaneModel {

protected final String name; 
protected final int capacity; 
protected int fuel; 
protected final int consumption; 
protected boolean hasLanded; 
protected final int LANDING_TIME; 
protected Airport airport; 

public AirplaneThread(String name, int capacity, int fuel, int consumption, int LANDING_TIME, Airport airport){ 
    this.name = name; 
    this.capacity = capacity; 
    this.fuel = fuel; 
    this.consumption = consumption; 
    this.LANDING_TIME = LANDING_TIME; 
    this.hasLanded = false; 
    this.airport = airport; 
} 


@Override 
public void run() { 
    while(!hasLanded){ 
     airport.requestLane(); 
    } 
} 


public synchronized void land(Lane lane){ 
    try{ 
     lane.changeState(false); 
     lane.getText().setText(toString()); 
     airport.notifyOut(3); 
     sleep(LANDING_TIME); 
     hasLanded = true; 
     lane.changeState(true); 
     airport.landingIsOver(lane); 
    }catch(InterruptedException e){ } 
} 

パブリッククラスレーンを{実装拡張するパブリック・クラス:ここのおかげとは、関連するコード(私はそれは少しくらい知っている)であります

private JTextField plane; 
private JCheckBox open; 
private boolean isclear; 
private int number; 

public Lane(JTextField plane, JCheckBox open, JLabel label, int number){ 
    this.plane = plane; 
    this.open = open; 
    this.isclear = false; 
    this.number = number; 
} 

public void changeState(boolean state){ 
    this.isclear = state; 
} 

public boolean isClear(){ 
    return isclear; 
} 

また、私が開いているときはいつも、このコードはセンチネルにもあります私のGUIでのレーン:あなたは空港のインスタンスで同期いくつかの方法において

laneB.addActionListener(new ActionListener() { 
@Override 
public void actionPerformed(ActionEvent e) { 
     //basically this returns the lane which checkbox i clicked 
     Lane lane = CenterPanel.getLanes().get(j-1); 
     if(lane.getCheck().isSelected()){ 
      airport.removeLane(lane); 
      lane.close(); 
     }else{ 
      lane.open(); 
      airport.start(); 
      airport.addLaneOpen(lane); 
     } 
     } 
    });  
+1

ブライアン・ゲッツ氏の言葉:「並行プログラムの作成は、シングルスレッドプログラムを作成するよりも難しくなります。何かが間違っている可能性があり、エラーを検出するのがはるかに難しくなる可能性があるからです。 – scottb

答えて

0

は、他の方法であなたはlanesOpenオブジェクトを使用します。この方法では、addLaneOpenでレーンを追加するとrequestLaneメソッドの待機が通知されることはありません。私はどこでも空港のオブジェクトに簡単に同期する必要があり、レーンが追加されたメソッドに通知を追加する必要があると思います。

一般的には、スレッドダンプを取得した場合(IDE、jstackまたはjvisualvmを使用して)、問題の内容を簡単に知ることができます。どのような種類のオブジェクトを待っているスレッドがあるのでしょうか。それからすぐにあなたのバグを見つけるでしょう。

+0

ありがとう、私はそれを試してみます。 – GamerGirl

+0

ええ、その方法はスレッドロックを引き起こしますが、IDEを使用して何が原因であるかを調べます。 – GamerGirl

+0

ここにすべてのニュースはありますか?解決済みですか? :) –

関連する問題