我正在尝试更新在Swing GUI后面运行的工作线程,我发现一旦Thread启动它似乎忽略了任何被更改/更新的参数等。
连接类:
@Override
public void run() {
initilizeConnection();
while (processing == true) {
if (connected == true) {
fetchFolders();
System.out.println("New Folder selected: "+directory);
if (directory == null) {
directory = "INBOX";
}
fetchMessages();
}
}
}
public void setDirectory(String directory) {
this.directory = directory;
}
GUI结束:
private void providerListMouseClicked(java.awt.event.MouseEvent evt) {
this.alisas = providerList.getSelectedValue().toString();
if (this.alisas != null) {
getThreadEmails().setNick(this.alisas);
Thread r = new Thread(getThreadEmails());
r.start();
if (getThreadEmails().isConnected() == true) {
populateFoldersList();
populateTable();
}
}
}
一旦用户点击了列表中的某个项目,就会存储该值,这会传递给连接类,这部分可以工作,但是当从另一个列表中选择一个文件夹并将其传递给该线程时,运行方法仍然说目录有空。
private void updateTable() {
dir = folderList.getSelectedValue().toString();
getThreadEmails().setDirectory(dir);
populateTable();
}
我花了好几个小时试图解决这个问题,但无济于事。
答案 0 :(得分:0)
您可能需要向我们展示更多代码,才能真正了解您尝试做的事情。
您的术语存在基本问题。您并没有尝试与线程交谈,而是在尝试与线程内运行的对象进行通信。因此,当您创建Thread并启动它时,如果您需要稍后与该对象通信,则需要保留一个句柄。
因此,让我们假设您有Thead a(您的主UI线程)和Thread b(您的电子邮件处理程序人员)。在线程a内运行的OBJECT保持在线程b内运行的OBJECT的句柄。调用处理emailHandler。
然后在某个时刻,用户做了一些事情。然后你的代码会:
emailHandler.doSomething(arguments);
你可以让doSomething()在你的对象中操纵你想要的任何东西。但问题是,doSomething()将在Thread a中调用,而不是在线程b中调用。
所以你可能需要你的EmailHandler对象来检查你操纵的值,所以他知道他应该做点什么。你可能需要使用wait()和notify()让线程唤醒....
多线程编程不适合弱者。我们大多数人通过阅读一些书来学习如何。
我花了一些时间思考这个问题。我将分享您想要了解的设计模式。
你有两个主题。一个线程需要将工作传递给另一个线程。我们使用的模式非常简单。
public class WorkQueue {
private ArrayList<WorkItem> list = new ArrayList<WorkItem>();
public synchronized void giveWork(arguments) {
WorkItem item = new WorkItem();
... set fields on item that describe what the other thread should do
list.add(item);
notifyAll();
}
public synchronized WorkItem getSomethingToDo() {
while (list.size() == 0) {
try {
wait();
}
catch (InterruptedException e) { }
}
WorkItem item = list.get(0);
list.removeAt(0);
return item;
}
}
然后你的工作线程看起来像:
WorkItem item;
while ((item = workQueue.getSomethingToDo()) != null) {
// do whatever you're supposed to do
}