无法在线程之间传递参数

时间:2015-03-12 17:28:53

标签: java multithreading

我正在尝试更新在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();
}

我花了好几个小时试图解决这个问题,但无济于事。

1 个答案:

答案 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
 }