java SwingWorker 从 doInBackground() 启动可运行对象以及如何通知事件调度线程
刚刚学习了 SwingWorker
并有一个问题
(我正在寻找这个问题的答案,但没有专门解决这个设置)
我正在创建一个小型服务器,最多只有 2-3 个同时连接。
我使用的 Jframe
具有内部类 SwingWorker
在 SwingWorker doInBackground()
我有:
while(true) {
Socket client_socket = listen_socket.accept();
Connection con = new Connection(client_socket, "name");
Future<Connection> future = es.submit(con , con );
tasks.add(future);
}
Connection
是一个可运行的对象,并在 SwingWorker
中声明为子类。
在 runnable
完成之前,它会在 SQL 中写入一个条目。
那么这个可运行程序如何在终止之前向 Jframe
事件调度线程发送一个提示。Jframe
将检查新条目的 SQL 并将其显示给用户。
最好做什么:
1 - 创建一个接口,所有可运行对象都可以向 Jframe 事件调度线程发送消息。
2 - 对所有新连接使用 SwingWorker
插入 runnables
并让 Done()
调用服务器 SwingWorker
中的方法使用 EventQueue.invokeLater..
调用 Jframe
中的方法
3 - 或使用 PropertyChangeListener (不知何故不确定)
4 - 让每个可运行对象都有 s引用 Jframe
并执行 EventQueue.invokeLater..
just learnd the SwingWorker
and have a question
( i have search for a answer to this but non specifically address this setup)
Im creating a small server that will have like max simultaneous 2-3 connections only.
Im using a Jframe
that have the inner class SwingWorker
In the SwingWorker doInBackground()
i have the:
while(true) {
Socket client_socket = listen_socket.accept();
Connection con = new Connection(client_socket, "name");
Future<Connection> future = es.submit(con , con );
tasks.add(future);
}
The Connection
is a runnable
and declared as a subclass in SwingWorker
.
Before the runnable
has completed it write an entry in the SQL.
How can then this runnable before it dies send a heads-up to Jframe
event dispatch thread.
and the Jframe
will check the SQL for the new entry and display it to user.
what is best to do:
1 - create an interface witch all runnable can send messages to Jframe
event dispatch thread.
2 - use SwingWorker
insted of runnables
for all new connections and have Done()
call a method in server SwingWorker
that call method in Jframe
using EventQueue.invokeLater..
3 - or use a PropertyChangeListener (somehow no sure)
4 - Let each runnables have s ref to Jframe
and do EventQueue.invokeLater..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
SwingWorker
文档非常清楚。您应该子类化SwingWorker
并在doInBackground()
方法中执行长任务。您应该在done()
方法中更新 UI。确实就是这么简单。
编辑:
为了说得更清楚。假设您的
Connection
类扩展了SwingWorker
,它不需要需要实现Runnable
并且您也不需要 需要显式提供一个线程池来运行工作线程。只需将run()
方法的内容放入doInBackground()
中即可。现在你的主循环看起来像这样;
您似乎正在主循环中提交给
ExecutorService
。是否有特定的原因(请注意,SwingWorker 为工作线程管理其自己的内部 ThreadPoolExecutor)。是限制并发客户端数量吗?如果是这样,还有其他方法可以实现这一点。The
SwingWorker
docs are pretty clear. You should subclassSwingWorker
and perform the long task in thedoInBackground()
method. You should update the UI in thedone()
method.It really is as easy as that.
Edit:
To make it clearer. Assuming your
Connection
class extendsSwingWorker
it does not need to implementRunnable
and you do not need to explicitly provide a thread pool to run the workers in. Just put the contents of therun()
method indoInBackground()
.Now your main loop looks something like this;
You seem to be submitting to an
ExecutorService
in your main loop. Is there a specific reason for this (note that aSwingWorker
manages its own internalThreadPoolExecutor
for worker threads). Is it to limit the number of concurrent clients? If so there are other ways to accomplish this.我会采取以下措施:在父线程中有一个线程安全的阻塞队列或列表,将传递给工作线程。任务完成后,工作线程会将包含结果条目 ID 的消息发布到此阻塞队列中。父线程将阻塞在队列中等待子线程的结果。每当队列中有一个元素时,父线程就会获取它并从数据库中获取该数据并将其显示给用户。
I would go for the following: have a thread safe blocking queue or list in the parent thread that will be passed to worker threads. Once a task is done, a worker thread will post a message that contains the result entry ID into this blocking queue. The parent thread will block on the queue waiting for results from child threads. Whenever there is an element in the queue, the parent thread will take it and go get that data from DB and display it to user.
我尝试创建一个生成后台工作线程的 SwingWorker 示例,其结果通过固定池 ExecutorService 和 CompletionService 发布。我仍然对在一个线程内创建工作线程,然后在另一个线程(SwingWorker 后台线程)内调用它们的 future 的线程安全性有一些疑问。
例如:
欢迎指正!
I tried to create an example of a SwingWorker that generates background worker threads, the results of which get published via a fixed pool ExecutorService and a CompletionService. I still have some questions regarding the thread safety of creating the worker threads inside of one thread, and then calling get on their futures inside of another thread (the SwingWorker background thread).
for example:
Corrections most welcome!