2012-05-11 6 views
0

Javaに問題があります。 文字を書くだけのクラス(クラスタスク)のスレッドのArrayListを持つClass Mainがあるプログラムを作成したいと思います。 Object Mainはただ1つのThreadをArrayListから復帰させ、同じオブジェクト(Main)が別のスレッドをスリープさせる間に何かを実行させます。 しかし、私はクラスのタスクで違法状態のエラーが表示されます。ArrayListからのスレッドの再開と中断

while(suspended){ 
wait(); 
    System.out.println(character); 
     } 

全体コード

import java.util.ArrayList; 


public class Main extends Thread { 
ArrayList<Thread> threads; 
public Main() { 
    super(); 
    threads = new ArrayList<Thread>(); 
} 

public void run(){ 
    for(int i = 0; i < 1; i++){ 
     threads.add(new Thread(new Task(i+65))); 
    } 
    long cT = System.currentTimeMillis(); 
    for(int i = 0; i < threads.size(); i++){ 
     threads.get(i).start(); 
    } 
    while(System.currentTimeMillis() - cT < 10000){ 
     for(int i = 0; i < threads.size(); i++){ 
      threads.get(i).start(); 
      try { 
       Thread.sleep(1000); 
      } catch (Exception e) {e.printStackTrace(); 
      } 
      threads.get(i).stop();; 
     } 
    } 


} 




public static void main(String[] args) { 
// new Main().start(); 
    new Thread(new Task(65)).start(); 

} 

} 


public class Task implements Runnable { 
int nr; 
char character; 
boolean suspended, resumed, stopped; 
public Task(int literaASCII) { 
    this.nr = 0; 
    character = (char) (literaASCII); 
    suspended = true; 
    resumed = true; 
    stopped = false; 
} 

@Override 
public void run() { 
    while(true){ 
     try{ 
     while(suspended){ 
      wait(); 
      System.out.println(character); 
     } 
     if(resumed){ 
      System.out.println("(Wznawiam watek litera: "+character+")"); 
      resumed = false; 
     } 
     System.out.print(nr+""+character+", "); 
     nr++; 
     int r = (int)((Math.random()*500) + 500); 
     Thread.sleep(r); 
     }catch(Exception e){e.printStackTrace();} 
    } 
} 

synchronized public void suspend(){ 
    suspended = true; 
    resumed = false; //chyba zbedne 
} 

synchronized public void resume(){ 
    suspended = false; 
    resumed = true; 
} 


public static void main(String[] args) { 
    // TODO Auto-generated method stub 

} 


} 

答えて

0

someObject.wait()は、someObjectで同期されたスレッドによってのみ呼び出すことができます。 waitのJavaDocには次のように書かれています。

現在のスレッドはこのオブジェクトのモニタを所有している必要があります。言い換えれば (source

、これが壊れている:

someObject.wait(); 
wait(); 

これが有効な間:

synchronized(someObject) { 
    someObject.wait(); 
} 
synchronized(this) { 
    wait(); 
} 

しかし、あなたがnotifynotifyAllを呼び出すことはありませんという事実は疑わしいです。

実装しようとしているのはブロッキングキューです.1つのスレッドはアイテムをそのスレッドに置き、もう1つのスレッドはそれらを取り出して処理します。その場合は、BlockingQueueを調べる必要があります。

+0

ありがとう、私はそれを修正しましたが、そのように見えます – Yoda

2

あなたがThread.start()のJavadocを読めばあなたはそれが言う見つける:

スレッドを複数回起動することは決して正当ではありません。特に、 スレッドは、実行が完了すると再開されないことがあります。

これは、あなたが違法な状態から来ている場所です。

また、Object.wait()を呼び出してもnotify()は呼び出されませんでした。これにより、自分が行っていることをほとんど知らないと思うようになりました。ですから、あなたは本を手に入れて、Javaでマルチスレッドと同期について読むことをお勧めします。難しい話題ですが、いったんそれを入手すれば、それは非常に有益なことになります。