2012-10-29 68 views
1

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

+0

可以调用get方法,要知道,你是从一个不同的线程这意味着该字段可以在阅读的更新,所以你可能会结束读取旧的值,则当前通话。您可以在int字段中使用volatile来确保字段上没有任何JVM优化,从而获得缓存值。 – breezee

+0

好的,所以线程按预期工作,但一旦我调用它的start()方法,父线程就会挂起。是因为我使用了一个while(true)循环吗?在父线程运行之前,我是否需要获得线程收益? –

回答

1

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

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

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

0

您应该在分组接收器线程类的传入数据包计数字段上进行同步getter方法。

请参阅此page以获取有关此概念的快速教程。

0

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

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

要点

  • 添加和等待应该是同步的(DataList控件)的代码块
  • addlast仅和removeFirst
  • 删除,请不要使用得到
  • 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 
          // 
         } 
        } 
    }