gpt4 book ai didi

java - 从事件调度线程 (EventQueue) 停止另一个线程

转载 作者:行者123 更新时间:2023-11-29 08:33:45 25 4
gpt4 key购买 nike

我有一个扩展 JDialog 的登录表单,用户可以通过刷卡或输入用户名和密码登录。

我创建了一个 Runnable 守护程序,它与磁条阅读器通信,启动时它会请求刷卡,它会一直等到有人刷卡。如果应用程序需要取消执行其他操作的请求,那么它将产生一个事件,该线程将捕获该事件,从而取消等待刷卡的请求。

当用户刷卡时,应用程序将读取用户 ID 的轨道并对其进行验证,如果身份验证成功,将向刷卡守护进程发送停止命令并停止线程。

当用户输入用户名和密码时,swing 包将访问一个线程 (AWT-EventQueue-0),该线程响应登录按钮的单击事件并继续评估登录凭据。

我的问题是,每当应用程序在此 AWT-EventQueue-0 线程上时,向刷卡守护进程发送停止事件将不起作用,守护进程将停留在线程堆栈中。

编辑 1: 停止命令在刷卡登录时运行良好。它优雅地结束刷卡线程。在这种情况下,当前线程范围在 CardSwipeThread 上。

问题发生在手动登录时,当用户单击登录按钮时,当前作用域线程将是 AWT-EventQueue-0 或事件调度线程。将 CardSwipeThread 的可变 boolean 值更新为 false 不会阻止它运行。

编辑 2: 读者与应用程序通信的唯一时间是刷卡时,问题发生在不需要刷卡的手动登录上。因此,由于 IO 操作受阻,CardSwipeThread 没有正确结束是没有问题的。 事实证明,有一个隐藏在灌木丛后面。

这是我的代码的一部分:

LoginDialog.java

public class LoginDialog extends JDialog implements ActionListener, WindowListener
{
public LoginDialog()
{
super();

// ..More code that instantiates the objects of this JDialog.

SwipeReader.getInstance().enable(true);
}

class SymAction implements java.awt.event.ActionListener
{
public void actionPerformed(java.awt.event.ActionEvent event)
{
Object object = event.getSource();
if (object == logonButton)
{
logonButton_actionPerformed(event);
}

// ..More conditions for other objects.
}
}

// The keyboard login method, does not terminate the card swipe daemon thread.
void logonButton_actionPerformed(java.awt.event.ActionEvent event)
{
try
{
// ..More code that will evaluate login information.

if (authenticate == -1)
{
// Notify for failed login.
}
else if (authenticate == 0)
{
SwipeReader.getInstance().enable(false);
}
}
catch (Exception e)
{
// Error logger.
}
}

// The card swipe listener used for card login.
public void deviceDataReceived(Object object)
{
try
{
// ..More code that will evaluate login information.

if (authenticate == -1)
{
// Notify for failed login.
}

if (authenticate == 0)
{
SwipeReader.getInstance().enable(false);
}
}
catch (Exception e)
{
// Error logger.
}
}
}

SwipeReader.java

public class SwipeReader
{
// This is a singleton class that creates the thread for the daemon.

CardSwipeDaemon cardSwipeDaemon;
Thread cardSwipeThread;
SwipeReader instance;

private SwipeReader() {}

public static SwipeReader getInstance()
{
if (instance == null) { instance = new SwipeReader(); }
return instance;
}

public void enable (boolean isEnabled)
{
if (isEnabled)
{
cardSwipeDaemon = new CardSwipeDaemon();
cardSwipeThread = new Thread(cardSwipeDaemon, "CardSwipeThread");
cardSwipeThread.start();
}
else
{
cardSwipeDaemon.stop();
cardSwipeThread = null;
}
}
}

CardSwipeDaemon.java

public class CardSwipeDaemon implements Runnable
{
CardSwipeDaemon instance;
private static volatile boolean listenforswipe = true;

public CardSwipeDaemon() {}

public static synchronized CardSwipeDaemon getInstance()
{
if (instance == null) { instance = new CardSwipeDaemon(); }
return instance;
}

public run()
{
listenforswipe = true;
while (listenforswipe)
{
// Code for reading the magnetic stripe data.
}
}

public void stop()
{
listenforswipe = false;
}
}

最佳答案

考虑使用 SwingWorker<Boolean, Boolean> 在这种情况下。你会 execute()工作人员在显示登录对话框之前。在您的 doInBackground() 实现中对读者进行投票和 publish()结果是否以及何时可用。您执行的 process() ,它在 event dispatch thread 上执行, 可以 close读者身份验证成功时的对话框。因为SwingWorker工具 Future , 你可以 cancel()如果键盘登录成功,工作人员。参见 Worker Threads and SwingWorker标记以获取更多示例。

This would require me a bit of rework on the code.

我认为付出努力是值得的,但在过于激进地重构之前,您需要运行几个示例。要查看数据流,试试这个 example从伪设备读取。怎么看cancel()有效,试试这个 example运行任意 Process .

关于java - 从事件调度线程 (EventQueue) 停止另一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45831541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com