Search code examples
javamultithreadingsleepwakeup

Resuming and suspending Threads from ArrayList


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

}


}

Solution

  • 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.