Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java UDP-多线程_Java_Multithreading_Udp - Fatal编程技术网

Java UDP-多线程

Java UDP-多线程,java,multithreading,udp,Java,Multithreading,Udp,基本上,我有一个图形化的swing应用程序。我需要使用UDP发送和接收数据,但我不希望应用程序代码中有任何接收(数据包)调用。我决定在一个单独的线程上运行程序的接收端。线程有一个int字段,该字段更新为来自传入数据包的值。如何从线程获取此字段的值。我可以只调用该字段的get方法,还是必须先中断线程?您应该在packetreceiver线程类的传入packet count字段上创建一个synchronized getter方法 有关此概念的快速教程,请参见此部分。您应该在packet Receiv

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

您应该在packetreceiver线程类的传入packet count字段上创建一个synchronized getter方法


有关此概念的快速教程,请参见此部分。

您应该在packet Receiver线程类的incoming packet count字段上创建一个synchronized getter方法


查看这一概念的快速教程。

< P>尽管GUI线程可以安全地读取int GETTE(假设适当的同步或易失性变量),考虑使用时间,因为它会使应用程序更加响应。基本上用SwingWorker对象替换自定义线程。您现在在
run()
中的代码进入
SwingWorker.doInBackground()

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


这样就不需要创建计时器来轮询UDP线程的getter。UI是更响应的,因为接收->发布->进程序列非常快。

< P>尽管GUI线程可以安全地读取int GET(假设适当的同步或易失性变量),考虑使用时间,因为它会使应用程序更加响应。基本上用SwingWorker对象替换自定义线程。您现在在
run()
中的代码进入
SwingWorker.doInBackground()

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


这样就不需要创建计时器来轮询UDP线程的getter。用户界面响应更快,因为接收->发布->过程序列非常快。

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

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

要点

  • 添加和等待应该在同步(数据列表)代码块中
  • 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
                 //
            }
        }
    }
    

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

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

要点

  • 添加和等待应该在同步(数据列表)代码块中
  • 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
                 //
            }
        }
    }
    

您可以调用get方法,但请注意,您是从不同的线程调用的,这意味着该字段可以在读取时更新,因此您可能会结束读取旧值而不是当前值。您可以在int字段中使用volatile,以确保在获取缓存值时不会对该字段进行任何JVM优化。好的,因此线程按预期工作,但只要我调用其start()方法,父线程就会挂起。是因为我在使用while(true)循环吗?在父线程可以运行之前,我是否需要线程产量?您可以调用get方法,但请注意,您是从另一个线程调用的,这意味着该字段可以在读取时更新,因此您可能会结束读取旧值而不是当前值。您可以在int字段中使用volatile,以确保在获取缓存值时不会对该字段进行任何JVM优化。好的,因此线程按预期工作,但只要我调用其start()方法,父线程就会挂起。是因为我在使用while(true)循环吗?在父线程可以运行之前,我是否需要线程产量?