سؤال

I have a problem with Java. I would like to write a program where there is Class Main which has ArrayList of Threads of some class (Class Task) which just writes a letter and the number. Object Main just wakes one Thread from ArrayList and let it to do something while the same object(Main) sleeps another one. But i get the error of Illegal state in class Task:

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

The whole Code

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

}


}
هل كانت مفيدة؟

المحلول

someObject.wait() may only be invoked by a thread that is synchronized on someObject. The JavaDoc for wait mentions this:

The current thread must own this object's monitor. (source)

In other words, this is broken:

someObject.wait();
wait();

while this is valid:

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

But the fact that you never call notify or notifyAll is suspicious.

It sounds like what you're trying to implement is a blocking queue: one thread puts items onto that thread, and the other thread takes them off it and processes them. If that's the case, you should look into BlockingQueue.

نصائح أخرى

If you read the Javadoc for Thread.start() you'll find it says:

It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

That's where you illegal state is coming from.

Also, you called Object.wait() but never called notify(), which lead me to believe you have very little idea of what you're doing. So I suggest you pick up a book and read about multi-threading and synchronisation in Java. It's a hard topic, but once you got it, it's going to be very rewarding.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top