为什么我的代码抛出了IllegalMonitorStateException?

时间:2015-02-10 17:49:02

标签: java multithreading

我试图理解线程如何在Java中工作。因此,我写了一小段代码,通过创建两个线程,一个打印所有奇数和其他打印偶数,并尝试在它们之间进行同步,以便按顺序打印所有数字。

public class Main 
{

    public static void main (String args[]){

        Main lock = new Main();

        Test t1 = new Test(1, lock);

        Test t2 = new Test(2, lock);

        synchronized(lock){

            (new Thread(t1)).start();
            (new Thread(t2)).start();

        }


    }

}

public class Test implements Runnable {


    int n;
    Main lock;

    public Test(int newN, Main lockObj){
        this.n = newN;
        this.lock = lockObj;
    }


    public void run() {


        while(true){

            if (n != 1){
                try {
                    lock.wait();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }

            n = n + 2;

            System.out.println(n);

            lock.notify();

        }


    }


}

有人可以帮助了解潜在的问题是什么吗?

2 个答案:

答案 0 :(得分:6)

您有三个主题,main主题,t1t2。线程 拥有 锁可以使用操作notifynotifyAllwait。在这种情况下,main主题拥有的锁不是t1t2

您需要在每个帖子的run方法中进行同步才能wait


以下是synchronizing方法中run的含义示例。

启动线程后从run方法发生的任何操作都将由该线程运行完成。因此,当您尝试wait时,您需要确保线程拥有锁,您可以通过在run方法中同步它来完成此操作。

public void run() {
     synchronized(lock){
         while(true){
            if (n != 1){
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
               }
            }
            n = n + 2;
            System.out.println(n);
            lock.notify();
        }
    }
}

正如您所看到的,我正在run方法中进行同步,以便t1t2在通知或等待时拥有锁。

答案 1 :(得分:0)

这可能无法帮助您理解低级线程机制,但对于您的情况,使用带有barrierAction的CyclicBarrier是有意义的。

在处理n = n + 2之后让两个踏板等待障碍物,让barrierAction sysout都是线程的当前n,重复。