2012-05-11 5 views
0

У меня проблема с Java. Я хотел бы написать программу, в которой есть класс Main, у которого есть ArrayList Threads некоторого класса (Task класса), который просто пишет букву и номер. Объект Main просто пробуждает один поток из ArrayList и позволяет ему что-то делать, в то время как тот же объект (Main) спит другой. Но я получаю ошибку Illegal состояния в классе Задача:Возобновление и приостановление потоков от 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. В JavaDoc для wait упоминается следующее:

Текущий поток должен принадлежать этому объекту. (source)

Другими словами, нарушается:

someObject.wait(); 
wait(); 

в то время как это справедливо:

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

Но тот факт, что вы никогда не называйте notify или notifyAll подозрительна.

Похоже, что вы пытаетесь реализовать, это блокирующая очередь: один поток помещает элементы в этот поток, а другой поток отключает их и обрабатывает их. Если это так, вы должны посмотреть на BlockingQueue.

+0

Спасибо, теперь я исправил его, но похоже, что это – Yoda

2

Если вы читали Javadoc для Thread.start() вы найдете это говорит:

Нельзя начинать нить более одного раза. В частности, поток не может быть перезапущен после завершения выполнения.

Вот откуда вы незаконное государство.

Кроме того, вы вызвали Object.wait(), но никогда не вызывали notify(), что заставило меня поверить, что вы очень мало представляете, что вы делаете. Поэтому я предлагаю вам взять книгу и прочитать о многопоточности и синхронизации на Java. Это трудная тема, но как только вы ее получите, это будет очень полезно.