2017-08-28 87 views
4

我想学习多线程和练习,我试图打印奇数&偶数使用两个线程。我创建了一个对象,它将充当这两个线程的锁。当我尝试执行它时抛出java.lang.IllegalMonitorStateException使用多线程打印奇数和偶数

class EVENODDimpl implements Runnable { 
    int num; 
    int temp = 0; 
    Object lock = new Object(); 

    public EVENODDimpl(int num) { 
     this.num = num; 
    } 

    public void run() { 
     try { 
      synchronized (lock) { 
       while(temp<num) { 
        temp++; 
        System.out.println(Thread.currentThread().getName()+" "+temp); 
        this.notify(); 
        this.wait(); 
       } 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

主要方法:

public class EVENODD { 
    public static void main(String[] args) { 
     int i = 10; 
     EVENODDimpl ei = new EVENODDimpl(i); 
     Thread t1 = new Thread(ei,"EvenThread"); 
     Thread t2 = new Thread(ei,"OddThread"); 
     t1.start(); 
     t2.start(); 
     try { 
      t1.join(); 
      t2.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

我认为问题是,你正在同步一个对象,但然后调用另一个“通知”和“等待”。 – Tavo

回答

3

waitnotifythis,但你应该waitnotifylock因为你lock同步,你不能waitnotify其他对象不是你是我的唯一同步,工作版本:

class EVENODDimpl implements Runnable { 
    int num; 
    int temp = 0; 
    Object lock = new Object(); 

    public EVENODDimpl(int num) { 
     this.num = num; 
    } 

    public void run() { 
     try { 
      synchronized (lock) { 
       while(temp<num) { 
        temp++; 
        System.out.println(Thread.currentThread().getName()+" "+temp); 
        lock.notify(); 
        lock.wait(); 
       } 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
3

当它从javadoc

抛出的异常表明某一线程已经试图等待对象的监视器,或者通知其他线程等待说一个对象的监视器没有拥有指定的监视器。

这意味着您的方法notifywait应该拥有自己的监视器。换句话说,调用这些方法的对象必须同步。您的this对象不同步。这就是为什么你会得到这个例外。在你的情况下,从lock对象调用此方法。

你的逻辑还是错误的,但是你需要去探索它。

+0

我已更正并更改锁定。我可以打印奇数和偶数。我不知道我的逻辑是什么意思是错误的。如果有什么可以请你指出。 – crazyStart

+1

通过同步您不希望的整个方法concurent或并行执行。那对于整个想法是没有意义的。也许你需要一些更重要的任务。尝试解决问题,以及如何解决问题等等。尽管这不是关于这个问题的话题。 –

+0

完全同意你的看法。我正在尝试学习多线程,因此解决了我在网上找到的问题,但我无法找到相同的练习题。谢谢您的帮助。干杯 – crazyStart

1

java.lang.IllegalMonitorStateException发生异常是因为您在对象this.notify()上使用通知方法,但该对象未同步。 更换synchronized (lock)本:synchronized (this)