新的线程和调用线程将被阻塞Java Semaphore

时间:2015-10-13 06:11:22

标签: java swing concurrency semaphore

我的java swing程序有些麻烦。当ExportWithoutEntryPointFrm框架出现在自己的线程中时,我尝试停止我的主框架线程。 我用java.util.concurrent.Semaphore实现了它。 出现的Frame只显示一个空框架,不会显示按钮,标签等,并且两个线程都被阻止。我认为有一个死锁,但我找不到它。

新警告框架的代码,将从主框架调用:

public class ExportWithoutEntryPointFrm extends javax.swing.JFrame implements Runnable
{

    private Semaphore sema;
    private boolean decision = false;


    public ExportWithoutEntryPointFrm(Semaphore semaphore)
    {
        initComponents();
        this.setLocationRelativeTo(null);
        this.sema = semaphore;

    }

    @Override
    public void run()
    {
        this.setVisible(true);

        try
        {
            sema.acquire();

        }
        catch (InterruptedException e)
        {
            this.decision = false;
            this.sema.release();

            this.setVisible(false);

        }
    }
}

来自主框架的调用代码:

Semaphore waitForDecisionSema = new Semaphore(1, true);

ExportWithoutEntryPointFrm warningFrm = new ExportWithoutEntryPointFrm(waitForDecisionSema);

warningFrm.run();
waitForDecisionSema.acquire();

2 个答案:

答案 0 :(得分:3)

首先,调用Runnable的run()方法并不会启动新线程。

其次,即使它确实如此,也只能从事件派发线程中使用像JFrame这样的Swing组件。

第三:因为一旦完成这一行,所有事情都是从一个线程,即EDT完成的:

waitForDecisionSema.acquire();

EDT被阻止等待某个其他线程释放信号量,这种情况永远不会发生,因此EDT会被永久阻止,使您的GUI无响应。

你真的需要重新考虑你的设计。但我不知道你想要达到的目标,所以很难提出建议。鉴于你的信号量的名称,我认为你正在寻找的是一个模态JDialog,它会阻止用户在对话框关闭之前使用对话框的父框架。 / p>

答案 1 :(得分:2)

  

当ExportWithoutEntryPointFrm框架出现在自己的线程中时,我尝试停止我的主框架线程

嗯,这是一个巨大的矛盾,Swing是一个单线程框架,你可以在不同的线程中操作组件/框架/窗口,它不会工作,你最终会在问题没有结束,死锁是最明显的。

首先查看Concurrency in Swing了解更多详情。

现在,您可以使用许多机制将长时间运行或阻止代码卸载到单独的线程,并仍然与Swing进行交互,Swing Timer用于常规预定回调,SwingWorker很长时间运行或可能阻止呼叫,但支持回拨到EDT,使其易于使用,甚至SwingUtilities.invokeLater用于您没有其他选择的时间。

有关详细信息,请查看How to use Swing TimersWorker Threads and SwingWorker

虽然根据你的描述,我建议你真正想要的是一个模态对话框,它会在对话框可见时阻止当前帧/代码执行,但这将允许UI继续响应给用户。

有关详细信息,请参阅How to Make Dialogs