2017-06-09 17 views
0

私はJavaの初心者で、マルチスレッドを使用して2つの「ボート」が画面上で競合するプログラムを作成しようとしています。私は2つの線が画面の向こう側に並んでいる状態で作業するために糸通し部分を得ました。マルチスレッドプログラムでCountDownLatchを使用する方法

しかし、コマンドで同時にスレッドを開始したいので、CountDownLatchクラスが見つかりました。私は実際にそれをよく理解していませんでしたが、まだラッチを使用してそれを使用しようとしましたが、latch.countDown()を呼び出すまでスレッドを待ちます()。これはすべて正常に機能しましたが、どのスレッドが最初に終了したのかを知りたいので、メインメソッドでタイマーとifステートメントを使用して、どのスレッド/「ボート」が高速かを判断しました。

私の2つの問題は、何らかの理由で、すべてがrun()を2回実行しているかのように、すべてが2回印刷され、b。 ifステートメントは、記録された時間のどちらかが他の時間よりも長いとは思わないので、常にまっすぐにelseに進みます。私はこのすべてがCountDownLatchで作ったいくつかの混乱のせいだと感じていますが、それを理解する経験はありません。

主な方法:スレッド2と

package practice; 

import java.util.concurrent.CountDownLatch; 

public class Rower implements Runnable { 
    int meters = 2000; 
    double startTime, endTime, finalTime; 
    Thread t; 
    String name; 
    CountDownLatch latch; 
    Q timed; 
    public Rower(CountDownLatch latch, String name, Q timed) { 
     this.timed=timed; 
     this.latch = latch; 
     this.name = name; 
     t = new Thread(this, name); 
     t.start(); 
     System.out.println(); 
    } 

    public void run() { 
     try { 
      latch.await(); 
      double startTime = System.nanoTime(); 
      for (int i = 20; i >= 0; i--) { 
       System.out.println("|");// each - is 10 meters 
       Thread.sleep(100); 
     } 
      double endTime = System.nanoTime(); 
      double finalTime = endTime - startTime; 
      timed.getTime(finalTime,name); 

     } catch (InterruptedException e) { 
      System.out.println("GET OUT THE WAY!"); 
      System.out.println("race postponed to tommorow"); 
     } 

    } 

} 

サブクラス:スレッド1と

package practice; 

import java.util.Scanner; 
import java.util.concurrent.CountDownLatch; 
import java.util.*; 

public class Regatta { 
    public static void main(String[] args) { 
     Q timed = new Q(); 
     CountDownLatch latch = new CountDownLatch(0); 
     Thread t1 = Thread.currentThread(); 
     Scanner scan = new Scanner(System.in); 
     System.out.println("What team is rower 1 on?"); 
     String roweronename = scan.nextLine(); 
     System.out.println("What team is rower 2 on?"); 
     String rowertwoname = scan.nextLine(); 

     Rower r1 = new Rower(latch, roweronename, timed); 
     Team2 r2 = new Team2(latch, rowertwoname, timed); 

     try { 
      System.out.println("ATTENTION"); 
      t1.sleep(1000); 
      System.out.println("READY"); 
      t1.sleep(1000); 
      System.out.println("ROW!"); 
      System.out.println(); 
      System.out.println(roweronename.toUpperCase() + "    " + rowertwoname.toUpperCase()); 
      System.out.println("--------------------------------------------"); 
      new Thread(r1).start(); 
      new Thread(r2).start(); 
      latch.countDown(); 

     } catch (InterruptedException e) { 
      System.out.println("There was an error. Don't click out of the program."); 
     } catch (Exception e) { 
      System.out.println("There was another error"); 
     } 
     try { 
      r1.t.join(); 
      r2.t.join(); 
     } catch (InterruptedException e) { 
      System.out.println("interruption error occurred"); 
     } 
     double finalTimeOne = r1.finalTime; 
     double finalTimeTwo = r2.finalTime; 

     if (finalTimeOne < finalTimeTwo) { 
      System.out.println(roweronename.toUpperCase() + " HAS WON THE RACE!"); 
     } else if (finalTimeTwo < finalTimeOne) { 
      System.out.println(rowertwoname.toUpperCase() + " HAS WON THE RACE!"); 
     } else 
      System.out.println("Nobody won"); 
    } 
} 

サブクラス

:同期方法と

package practice; 
import java.util.concurrent.CountDownLatch; 

public class Team2 implements Runnable { 
    Q timed=new Q(); 
    int meters = 2000; 
    double startTime,endTime,finalTime; 
    Thread t; 
    String name; 
    CountDownLatch latch; 
    public Team2(CountDownLatch latch,String name, Q timed) { 
     this.timed=timed; 
     this.latch=latch; 
     this.name = name; 
     t = new Thread(this, name); 
     t.start(); 
     System.out.println(); 
    } 

    public void run() { 
     try { 

      latch.await(); 
      double startTime=System.nanoTime(); 

      for (int i = 20; i >= 0; i--) { 
       int j=20-i; 
       System.out.println("     |");// each | is 10 meters 
       Thread.sleep(100); 
      } 
      double endTime=System.nanoTime(); 
      double finalTime=endTime-startTime; 

       timed.getTime(finalTime, name); 


     } catch (InterruptedException e) { 
      System.out.println("GET OUT THE WAY!"); 
      System.out.println("race postponed to tommorow"); 
     } 

    } 

} 

クラスは、仕上げの時間を取得しますあなたの漕ぎ手(とTeam2)インサイド

答えて

0

クラスのコンストラクタには、新しいスレッドを初期化し、それを始めている。

public Rower(CountDownLatch latch, String name, Q timed) { 
    this.timed=timed; 
    this.latch = latch; 
    this.name = name; 
    //vvvvvvvv THIS IS THE PROBLEM vvvvvvvv// 
    t = new Thread(this, name); 
    t.start(); 
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// 
    System.out.println(); 
} 

あなたが漕ぎ手(またはTeam2)内部のスレッドを必要としません。あなたのレガッタクラスで作成されたスレッドは、漕ぎ手(とTeam2)で「実行」メソッドを呼び出すのに十分である

// These are all you need to get the boats to race! 
new Thread(r1).start(); 
new Thread(r2).start(); 

また、サイドノートとして:あなたは、あなたがすべき...全くTeam2クラスを必要としません2つのRowerオブジェクトを初期化することによって2つの異なるボートを競うことができます。

Rower r1 = new Rower(latch, roweronename, timed); 
// Changed from Team2 to Rower 
Rower r2 = new Rower(latch, rowertwoname, timed); 

1が別の1(セーリング対ボート、対モーターボートなど)とは異なる推進されたように2隻が、異なる機能を持っていた場合にのみ、二つの異なるボートクラスを持っている必要があります。あなたのケースでは、それらは本質的に同一であるように見えます(ほぼコピーペーストされます)。

+0

OH MY GOD、よろしくお願いします!しかし、第2の部分については、他のクラスの理由は、スレッドの1つが最初のスレッドからいくつかのスペースを離れて印刷する必要があったためです。最初のスレッドは "|"もう一方は "----------------------- |"を印刷していました。 – bobthebuilder

+0

あなたが提案しているようなカスタム値を印刷する方法がたくさんありますが、1つの方法では希望する値をaに渡すことになります。コンストラクタの引数を取得し、そのクラスに格納します。 'Rower(CountDownLatchラッチ、文字列名、Q timed、' 'Rower'')' 'Rower'' =文字列のテール) ''ローカルに設定する: 'this.tail = tail;'次にprintメソッドを更新します: 'System.out.println(tail);' – pacifier21

+0

それはとても明白でした。私.. – bobthebuilder

関連する問題