调用wait(),notify()或notifyAll()时如何获得相同的监视器?

时间:2015-04-13 09:09:17

标签: java multithreading

主线程创建这两个线程的两个线程t1和t2 run()方法创建两个新线程c1和c2.I想要一个场景,直到c1& c2(t1)处于活动状态t2才会开始执行。在我的代码中,notify和wait导致Runtime Exception。因为它们不在synchronized块中,怎么做?

public class childTcreat2newthread {

    public static void main(String[] args) throws InterruptedException {
        Thread mainT = Thread.currentThread();
        Target ra = new Target("a");
        Thread t1 = new Thread(ra);
        t1.start();
        t1.join();

        while (ra.getC1().isAlive() == true || ra.getC2().isAlive() == true) {
            synchronized (mainT) {
                mainT.wait();
            }
        }
        new Thread(new Target("b")).start();
    }
}

class Target implements Runnable {
    Thread c1 = new Thread(new Target1("1"));

    Thread c2 = new Thread(new Target1("2"));
    String msg;

    Target(String msg) {
        this.msg = msg;
    }

    @Override
    public void run() {

        for (int j = 0; j < 100000; j++) {
            for (int i = 0; i < 10000; i++) {
                if (i % 10000 == 0 && j % 10000 == 0) {
                    System.out.print(msg);
                }
            }
        }

        t1.start();

        t2.start();
    }

    public Thread getC1() {
        return c1;
    }

    public Thread getC2() {
        return c2;
    }
}

class Target1 implements Runnable {

    String msg;

    Target1(String msg) {
        this.msg = msg;
    }

    @Override
    public synchronized void run() {
        for (int j = 0; j < 100000; j++) {
            for (int i = 0; i < 100000; i++) {
                if (i % 100000 == 0 && j % 10000 == 0) {
                    System.out.print(msg);
                }
            }
        }
        try {

            notifyAll();
            System.out.println("K");
        } catch (IllegalMonitorStateException e) {
            System.out.println("\nIllegalMonitorStateException!! in " + msg + "\n");
        }
    }
}

wait()告诉调用线程放弃监视器并进入休眠状态,直到某个其他线程进入同一个监视器并调用notify()。调用notify时无法获得相同的监视器。如何去做这个? 它的重要性是什么?

3 个答案:

答案 0 :(得分:1)

您应该避免使用wait()/ notify(),并尽可能使用Java提供的更高级别的抽象,请参阅:Java Concurrency Tutorial

使用wait()/ notify(),您必须对两个呼叫使用相同的监视器,请参阅Guarded Blocks。即使这只是为了学习,我也没有看到使用wait()来完成这项工作的好方法。您应该坚持使用join()或使用其中一个更高级别的抽象。

答案 1 :(得分:1)

由于我没有足够的声誉来评论,通过回答发表评论

您没有锁定并通知同一个对象。

您锁定了mainT,但在Target1实例上通知,您需要将锁定对象传递给c1c2

但是我建议您使用java concurrent API来解决此类问题

答案 2 :(得分:0)

怎么样:

public static void main(String[] args) throws InterruptedException {
    Thread mainT = Thread.currentThread();
    Target ra = new Target("a");
    Thread t1 = new Thread(ra);
    t1.start();
    t1.getC1().join();
    t1.getC2().join()

    new Thread(new Target("b")).start();
}

请参阅:https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join%28%29