繁体   English   中英

Java中的多线程(两个线程同时使用notify()和wait())

[英]Multithreading in java (two threads extensively using both notify() and wait())

当我尝试运行以下程序时,在这段代码中的第一个通知()的调用中有一个IllegalMonitorStateException:

synchronized (c) {
    try {
        notify();
        ....

这让我有些不安:如果代码(c)已经在同步块中并检查了相同的锁,那么该代码怎么可能没有对它锁?

请不要介意对notify()和wait()的使用有些奇怪。 我知道有多种执行相同任务的(更有效的)实现方式,但是现在我试图弄清楚为什么这个特定的方式行不通。

完整的代码如下:

  class J implements Runnable {

        public static void main(String[] x) {
            Calc calc = new Calc();
            J j = new J(calc);
            Thread t1 = new Thread(j, "one");
            Thread tCalc = new Thread(calc, "Calc");
            tCalc.start();
            t1.start();
        }
        Calc c;
        public J(Calc c) {
            this.c = c;
        }

        public void run() {
            synchronized (c) {
                try {
                    notify();
                    c.wait();
                } catch (InterruptedException e) {

                }
                System.out.println(Thread.currentThread().getName() + ": x = "
                        + c.getX());
                notify();
            }
        }
    }

    class Calc implements Runnable {

        private int x;

        public int getX() {
            return x;
        }

        public void run() {
            synchronized (this) {

                for (int x = 1; x <= 11111; x *= (x + x)) {
                    this.x += x;
                    try {
                        notify();
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                notify();
            }
        }
    }

您正在尝试通知线程正在等待您当前未持有的其他锁。 该错误是合理的。 您在对象c上有一个锁,然后将当前对象上的锁通知其他线程。

synchronized (c) {
    try {
        notify();
        ....

您正在锁定对象c但是正在通知对象this 最好始终在将来明确指定要在哪个对象上使用wait()notify() 你应该做:

synchronized (c) {
    try {
        c.notify();
        ....

要么:

synchronized (this) {
    try {
        this.notify();
        ....

看来您实际上要处理2个锁。 如果是这种情况,则可以执行以下操作。

synchronized (c) {
    try {
        synchronized (this) {
            this.notify();
        }
        c.wait();

以确保您始终锁定是很重要的c第一,然后this ,否则你就会死锁。

您拥有的是执行以下操作的复杂方法。

ExecutorService printer = Executors.newSingleThreadExecutor();

int x2 = 0;
for (int x = 1; x <= 11111; x *= (x + x)) {
    x2 += x;
    final int x3 = x2;
    printer.submit(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + ": x = " + x3);
        }
    });
}
printer.shutdown();

如果您不尝试使用两个线程来完成比一个线程更快/更简单的操作,这将更加简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM