新线程和调用线程将被阻塞 Java 信号量

New thread and calling thread will be blocked Java Semaphore

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

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

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();

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

其次,即使是这样,像 JFrame 这样的 Swing 组件也必须只能在事件分派线程中使用。

第三:因为一切都是从单个线程 EDT 完成的,一旦执行此行:

waitForDecisionSema.acquire();

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

您真的需要重新考虑您的设计。但我不知道你想要达到什么目的,所以很难给出建议。鉴于您的信号量名称,我 认为 您正在寻找的是模态 JDialog,它将阻止用户使用对话框的父框架,直到对话框关闭。

I try to stop my main Frame thread when the ExportWithoutEntryPointFrm Frame appears in an own thread

好吧,这在术语上是一个巨大的矛盾,Swing 是一个单线程框架,你可以在单独的线程中操作 components/frames/windows,它不会工作,你最终会陷入无穷无尽的问题,死锁最明显。

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

现在,您可以使用多种机制将长 运行 或阻塞代码卸载到单独的线程,同时仍然与 Swing 交互,Swing Timer 用于定期计划的回调,SwingWorker 用于长时间 运行 或可能阻塞调用,但它支持对 EDT 的回调,使其易于使用,甚至 SwingUtilities.invokeLater 在那些你别无选择的时候。

查看 How to use Swing Timers and Worker Threads and SwingWorker 了解更多详情

尽管根据您的描述,我建议您真正想要的是模态对话框,它将在对话框可见时阻止当前 frame/code 执行,但允许UI 继续回复用户。

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