2015-07-09 3 views
0

Мне нужна помощь, чтобы понять, где моя программа идет не так, у меня есть очень простая программа, чтобы узнать о многопоточности, но каждый раз, когда я запускаю следующий код, это дает мне исключение IllegalStateMonitor. Я не знаю, что вызывает это, хотя я подозреваю это может быть мой синхронизированный блок, спасибо.Java IllegalMonitorStateException

Основной метод класса:

public class Lab8 { 
    public static void main(String [] args) { 
     Thread1 thread1 = new Thread1(); 
     thread1.start(); 
    } 
} 

Тема 1:

import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

public class Thread1 extends Thread { 
public DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 

public Thread1() { 
    super("Thread1"); 
} 
public void run() { 
    Thread2 thread2 = new Thread2(); 
    System.out.println("==Start: " + dateFormat.format(new Date()) + "==\n"); 
    synchronized(thread2) { 
     try { 
      this.wait(); 
     } catch (InterruptedException e) { 
      System.err.println(e.toString()); 
     } 
     (new Thread(thread2)).start(); 
    } 
    System.out.println("==End: " + dateFormat.format(new Date()) + "==\n"); 
} 
} 

Тема 2:

public class Thread2 implements Runnable { 
@Override 
public void run() { 
    synchronized(this) { 
     for(int i = 1; i <= 100; i++) { 
      System.out.print(i + " "); 
      if(i % 10 == 0) { 
       System.out.print("\n"); 
      } 
     } 
     notify(); 
    } 
} 

} 
+0

Если вы получаете исключение, полезно включить трассировку стека в ваш вопрос. – Holger

+0

Не просто включить его здесь, но и прочитать его сами. Если вы прочитали трассировку стека, вам не пришлось бы «подозревать, что это может быть [в] моем синхронизированном блоке:« У вас было бы _known_ именно то, что строка кода породила исключение. –

ответ

2

Вы должны понимать, что synchronized конструкция и механизм wait/notify являются привязан к экземпляру объекта. В коде, вы используете

synchronized(thread2) { 
    … 
     this.wait(); 

поэтому объект вашего synchronized заявления и один, вы вызываете wait на, различны. Это вызывает IllegalStateMonitorException. Обратите внимание, что ожидание на экземпляре Thread1, пока другой поток вызывает notify() сам по себе Thread2 экземпляр не будет работать, так как notify проснется только в ожидании в том же экземпляре.

Кроме того, вы никогда не должны синхронизировать экземпляры потоков в любом случае. Причина в том, что реализация Thread будет синхронизироваться и в своем собственном экземпляре, так что это может помешать. Кроме того, вы не должны подкласса Thread, как вы это делали со своим классом Thread1, а скорее используете композицию, как вы сделали с вашим классом Thread2.

+0

Да, кроме того, расширение 'Thread' на самом деле не _wrong_, это просто плохая конструкция. –

+0

@james large: Ну, я сказал «не должен» в конце заметки, но не должен быть догматическим правилом, однако здесь это шаблон, который приводит к случайной синхронизации или ожиданию экземпляра потока, просто используя 'this' ... – Holger