0

Javaに問題があります。文字と数字を書くだけのクラス(クラスタスク)のスレッドのArrayListを持つクラスMainがあるプログラムを書きたいと思います。Object Mainは、ArrayListから1つのスレッドをウェイクアップし、同じオブジェクト(Main)が別のスレッドをスリープしている間に何かを実行させます。しかし、私はクラスTaskでIllegalstateのエラーを受け取ります:

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

}


}
4

2 に答える 2

2

Javadoc を読むと、次のように書かれThread.start()ていることがわかります。

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

それがあなたの違法国家がどこから来ているかです。

また、あなたは Object.wait() を呼び出しましたが、notify() を呼び出したことはありません。これにより、自分が何をしているのかほとんどわからないと思います。ですから、本を手に取り、Java のマルチスレッドと同期について読むことをお勧めします。難しいトピックですが、一度取得すると、非常にやりがいのあるものになります。

于 2012-05-11T23:52:39.257 に答える
0

someObject.wait()で同期されているスレッドによってのみ呼び出すことができますsomeObject。JavaDoc forwaitはこれについて言及しています:

現在のスレッドは、このオブジェクトのモニターを所有している必要があります。(ソース

つまり、これは壊れています。

someObject.wait();
wait();

これは有効ですが:

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

しかし、あなたが決して電話をかけない、notifyまたはnotifyAll疑わしいという事実。

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

于 2012-05-11T23:57:14.830 に答える