1

基本上,我有一个图形摇摆应用程序。我需要使用 UDP 发送和接收数据,但我不希望应用程序代码中有任何接收(数据包)调用。我决定在一个单独的线程上运行程序的接收端。该线程有一个 int 字段,该字段更新为来自传入数据包的值。我将如何从线程中获取该字段的值。我可以只调用字段的get方法,还是必须先中断线程?

4

3 回答 3

1

尽管 GUI 线程可以安全地读取 int getter(假设有适当的同步或 volatile 变量),但请考虑花时间使用SwingWorker,因为它会使您的应用程序更具响应性。基本上,您将自定义线程替换为 SwingWorker 对象。您现在拥有的代码run()进入SwingWorker.doInBackground().

您启动工作程序,doInBackground代码在单独的线程中执行。大概这是一个UDP接收循环。当您的循环收到一个新的 int 时,您调用publish(仍在后台线程中)。这将导致在事件线程中调用另一个 SwingWorker 方法process(您已经用一些自定义代码覆盖了该方法)。在这里您可以安全地更新您的 GUI,因为您正在事件线程中运行。

这消除了创建计时器来轮询 UDP 线程的 getter 的需要。UI 响应更快,因为接收 -> 发布 -> 处理顺序非常快。

于 2012-10-29T02:41:52.923 回答
0

您应该在数据包接收器线程类的传入数据包计数字段上创建一个同步的 getter 方法。

有关该概念的快速教程,请参阅此页面

于 2012-10-29T02:21:38.567 回答
0

您在这里只有 1 个目标。UI 不应等待并挂起网络上的数据。您需要一个 LinkedList(不是 ArrayList),一个 dataJustArrived 方法,它通知您的 LinkedList 对象。一个正在运行一段时间 (true) 并在 LinkedList 上等待的线程。

dataJustArrived,将数据对象添加到链表并通知等待。等待解锁,并检查linkedList.lenght > 0,并从列表中删除(不是GETS,而是删除)数据并处理UI。

要点

  • 添加和等待应该在同步(dataList)代码块中
  • addLast 和 removeFirst
  • 删除,不要使用 get
  • LinkedList 会工作,ArrayList 不会工作(将是非常昂贵的操作)
  • 等待解锁后,检查 dataList.length > 0
  • 在等待之前,请检查 dataList.lenght > 0,如果有数据要处理,为什么还要等待?

    public synchronized void dataJustArrived(Object data) {
        synchronized (dataList) {
        dataList.addLast(data);
        this.notify();
        }
    }
    
    public void run() {
        Object data ;
        while (true) {
            synchronized (this) {
                 if (dataList.isEmpty()) {
                    try {
                       dataList.wait();
                    } catch (InterruptedException ignored) {
                       ignored.printStackTrace();
                    }
                 }
                 if (!dataList.isEmpty)
                     data = dataList.removeFirst();
                 //
                 // Process your UI here
                 //
            }
        }
    }
    
于 2012-10-29T04:28:16.427 回答