2016-04-26 14 views
0

これは、スレッドを同期させるためにMonitorを使用するマルチスレッドの方法です。私はモニタや同期化に問題はなく、デッドロックはありません。私は主にいくつかのスレッドを作成したい。以下のコードはスレッドを生成し、ArrayListに追加して開始します。スイッチケースで異なるスレッドを生成します。すべてのスレッドをArrayListに追加して開始する必要があるため、これらの2行をswitch-caseの最後に置いて、すべてのcase-stateで同じコードを書き込まないようにします。しかし、このようにして、IllegalThreadStateExceptionを起動します。スレッドを避けるために作成する方法IllegalThreadStateException

私のコードを動作させるために、私はさまざまなアプローチを適用できますが、私はそれらのすべてに疑念を抱いています。どちらが最も適切な方法でしょうか?

新しいmyThreadインスタンスを作成する関数を作成し、それをArrayListに追加して起動します。しかし、私はメインから呼び出す必要があるので、静的でなければなりません(正当な理由なく静的関数を作成することは良い習慣ではありません)。それはmyClassの多くのインスタンスを作成し、良いと思われません。

public class myClass { 

    public static void main(String[] args) { 

     int scount=10, tcount=5, pcount=5; 
     final int SIZE = 20; 


     ArrayList<User> users = new ArrayList<User>(); 
     myMonitor monitor = new myMonitor(SIZE); 
     User u = null; 
     int s = 0, t = 0, p = 0; //counters 

     //GENERATED CASUALLY DIFFERENT TYPE OF THREADS 
     while(s < scount || t < tcount || p < pcount){ 

      int type = (int)(Math.random() * 3); 

      switch(type){ 
      case 0: 
       if(p < pcount){ 
        u = new User(monitor, p, "USER_TYPE_1"); 
        p++;     
       } 
       break; 
      case 1: 
       if(t < tcount){ 
        u = new User(monitor, p, "USER_TYPE_2"); 
        t++; 
       } 
       break; 
      case 2: 
       if(s < scount){ 
        u = new User(monitor, p, "USER_TYPE_2"); 
        s++; 
       } 
       break; 
      } 
      users.add(u); 
      u.start(); 
     } 

    } 

} 

public class User extends Thread{ 
    myMonitor monitor; 
    final private int number; 
    final private String type; 
    final private int k; 
    final private int MIN = 1; 
    final private int MAX = 5; 


public User(myMonitor monitor, int number, String type) { 
    this.monitor = monitor; 
    this.number = number; 
    this.type = type; 
    this.k = (int)(Math.random() * ((MAX - MIN) + 1)) + MIN; 
} 

public int getNumber() { 
    return number; 
} 

public String getType() { 
    return type; 
} 

@Override 
public void run(){ 

    for(int i=0; i<k; i++){ 

     switch(this.type){ 
      case "TYPE1": 
       monitor.startType1(); 
       break; 
      case "TYPE2": 
       monitor.startType2(i); 
       break; 
      case "TYPE3": 
       monitor.startType3(); 
       break; 
     } 

     try{ 

      Long duration = (long) Math.ceil(Math.random() * 1000); 
      Thread.sleep(duration); 
      System.out.printf("%s-%d used system for the %d.time. Took %d ms\n", 
        this.type, this.number, i+1, duration); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     switch(this.type){ 
      case "TYPE1": 
       monitor.endType1(); 
       break; 
      case "TYPE2": 
       monitor.endType2(i); 
       break; 
      case "TYPE3": 
       monitor.endType3(); 
       break; 
     } 

     try{ 
      Long duration = (long) Math.ceil(Math.random() * 1000); 
      Thread.sleep(duration); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    } 
    System.out.printf("%s-%d finished\n", this.type, this.number); 
} 

}

+0

:さて、あなたは実際には乱数を生成したくないですか?このコードは絶対に意味をなさない。あなたはJavaで長いプログラミングをしていませんでしたか? – Kayaman

+0

これは単なるマルチスレッドの例です。私は同期などで問題がないので、コードを追加しませんでした。しかし今はそれを編集しました、私はそれがより明確であることを望みます。しかし、それはどのくらい私はJavaのプログラムに依存しない... – user3717434

答えて

0

考えてみると、Math.random * 3は常に0を返します。これは明らかにrandom(ちょっとそうは思われません)です。

反復1

int s == t == p == 0 

我々はtype == 0として、最初のケースを入力してください。新しい「P」ThreadおよびaddListおよびstart()に生成します。

p++ 

反復2

int s == t == 0; p == 1 

我々はtype == 0として、最初のケースを入力してください。新しい「P」ThreadおよびaddListおよびstart()に生成します。

p++ 

...

イテレーション5

int s == t == 0; p == 4 

我々はtype == 0として、最初のケースを入力してください。新しい「P」ThreadおよびaddListおよびstart()に生成します。

p++ 

反復6

int s == t == 0; p == 5 

我々はtype == 0ように、第1ケースを入力します。 p> = pcountとは何もしません。私たちのthrdは、Threadを作成しました。イテレーション5です。

我々はListstart()それに同じThreadを追加します。

IllegalThreadStateException 

は今、明らかに Math.random * 3は異なる値を返しますが、それは重複を返します(とあなたのコードがその周りに設計された) - あなたは この状況を取得します。

どうすればよいですか?あなたがする何をしようとしている

final List<Integer> desiredValues = new ArrayList<>(Arrays.asList(0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2)); 
Collections.shuffle(desiredValues) 
for(final Integer value : desiredValues) { 
    //case switch 
} 
+0

あなたはそうです、私はこの状況を認識しませんでした。 Collection.shuffle()は良いアドバイスです。ありがとう! – user3717434

+0

私のIDEはListが汎用ではないと言っています。引数でパラメータ化することはできません... – user3717434

+0

間違った 'List'。輸入品を確認してください。 –

0

新しいスレッドが作成されなかった場合でも、thrd.start();を呼んでいます。変数をループ外に宣言しているので、以前に開始したスレッドを参照します。スレッド上でstart()を2回呼び出すと、例外が発生します。

myThread thrd = null;ループをwhileループ内に移動し、ヌルでない場合はstart();を呼び出します。

+0

それは本当に必要ではない - 私の答えを参照してください。 OPはランダムな値ではなく、ランダムな順序で固定値のセットを生成したい。 –

+0

まあ明らかにそうではありません。私は元のものへの変更の最小量のために行っていた。 – Kayaman

関連する問題