Java线程问题

标签 java multithreading resume suspend

我在我的应用程序中使用了多个线程。基本上我有一个组合框,选择收件箱后,p1 恢复,p2 暂停,选择发送后,p2 启动,p1 停止。下面是代码(我敢肯定它并不完美)

public void modifyText(ModifyEvent e) {
                if (combo.getText().equals("Inbox"))
                {
                    synchronized(p2) 
                    {
                        p2.cont = false;
                    }
                    table.removeAll();
                    synchronized(p1)
                    {
                        p1.cont = true;
                        p1.notify();
                    }
                }


                else if (combo.getText().equals("Sent"))
                {
                    synchronized(p2) 
                    {
                        p1.cont = false;
                    }
                    table.removeAll();
                    synchronized(p1)
                    {
                        p2.cont = true;
                        p2.notify();
                    }
                }
            }
        });

对于 P1 和 P2,我在它们的 while 循环中有这个:

synchronized (this) {
            while (cont == false)
                try {
                    wait();
                } catch (Exception e) {
                }
        } 

... 现在它正在工作(我是线程的初学者)。在组合框中按下 Sent 时,我得到一个 IllegalStateMonitorException。有谁能帮我解决这个问题吗?

感谢和问候, Krt_马耳他

最佳答案

问题出在这里:

synchronized(p1)
{
    p2.cont = true;
    p2.notify();
}

当您还没有锁定p2 时,您正在执行p2.notify()(您必须按住监视器才能在其上调用notify)。将 synchronized(p1) 更改为 synchronized(p2)。此外,您还需要反转其他 synchronized 子句,这也是有问题的。因此,举个例子:

synchronized(p1) 
{
    p1.cont = false;
    // p1.notify(); <- do you need this here?
}
table.removeAll();
synchronized(p2)
{
    p2.cont = true;
    p2.notify();
}

此外,您的其他代码也有点错误,将整个循环锁定在内部是非常糟糕的做法,使其更具原子性。

while (!cont) {
    synchronized (this) {
       try {
           wait();
       } catch (Exception e) {
       }
    }
}

额外的优化,尽可能避免synchronized:

if (p1.cont) {
   synchronized(p1) 
   {
       p1.cont = false;
       // p1.notify(); <- do you need this here?
   }
}
table.removeAll();

if (!p2.cont) {
   synchronized(p2)
   {
       p2.cont = true;
       p2.notify();
   }
}

在这里使 cont 字段volatile,并根据需要镜像 if 语句的其他部分。

编辑:回顾这一点并与我最近面临的并发错误作斗争,任何实现此模式的人都可能面临无限等待的问题,如果条件正在查看被锁定和半锁定的对象while 循环(这是因为在评估条件和执行等待语句之间存在状态可以更改的间隙)。在这种情况下,将同步块(synchronized block)放在循环的外部

关于Java线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2456846/

相关文章:

java - 从 SQS 检索消息缓慢

java - 为什么我的 Android 设备上没有调用 LibGDX 的 resume() 方法?

video - 如何在编码期间暂停和恢复ffmpeg?

java - 为什么模拟器的随机性不如我的设备?

Java,流: how to convert expression with.收集(Collectors.toList())

java - 什么是NumberFormatException,我该如何解决?

iphone - cocos2d游戏如何实现暂停/恢复?

multithreading - 在 Clojure 中使用 pmap 来并行化归并排序。程序在结束前挂起约 1 分钟,然后终止

android - 在类里面获取 NULL 指针异常以检查互联网

Ruby 使用多线程运行两个脚本