当前位置: 首页 > 知识库问答 >
问题:

线程的运行未看到其数组大小增加

宇文鸿畴
2023-03-14

我目前正在做一个Java作业。我被要求创建一个基本的DNS服务器。有一个UDPSender类,它是一个监听端口53的线程。还有另一个线程叫做UDPManager。

UDPManager使用嵌套的可运行类启动线程,该类包含DatagramPacket的ArrayList。UDPSender聚合UDPManager,每当它接收到UDP数据包时,它都会将其发送给管理器,以便管理器将其添加到arrayList。

import java.net.DatagramPacket;
import java.util.ArrayList;
import java.util.HashMap;


public class UDPManager {
private UDPManagerRunnable manager;

public UDPManager(String hostsFile, String remoteDNS, boolean localResolution) {
    manager = new UDPManagerRunnable(hostsFile, remoteDNS, localResolution);
    new Thread(manager).start();
}

public void managePacket(DatagramPacket p) {
    manager.managePacket(p);
}

public void close() {
    manager.close();
}

private class UDPManagerRunnable implements Runnable {
    private ArrayList<DatagramPacket> packets;
    private HashMap<Integer, String> clients;
    private boolean localResolution;
    private boolean running;
    private String hostsFile;
    private String remoteDNS;

    public UDPManagerRunnable(String hostsFile, String remoteDNS, boolean localResolution) {
        packets = new ArrayList<DatagramPacket>();
        clients = new HashMap<Integer, String>();
        this.localResolution = localResolution;
        this.running = true;
        this.hostsFile = hostsFile;
        this.remoteDNS = remoteDNS;
    }

    public void managePacket(DatagramPacket p) {
        packets.add(p);
        System.out.println("Received packet. "+packets.size());
    }

    public void close() {
        running = false;
    }

    public void run() {
        DatagramPacket currentPacket = null;
        while(running) {
            if(!packets.isEmpty()) {
                currentPacket = packets.remove(0);
                byte[] data = currentPacket.getData();
                int anCountValue = data[Constant.ANCOUNT_BYTE_INDEX];
                if(anCountValue == Constant.ANCOUNT_REQUEST)
                    this.processRequest(currentPacket);
                else if(anCountValue == Constant.ANCOUNT_ONE_ANSWER)
                    this.processResponse(currentPacket);

            }
        }

    }

    private void processRequest(DatagramPacket packet) {
        System.out.println("it's a request!");
    }

    private void processResponse(DatagramPacket packet) {
        System.out.println("it's a response!");
    }

}

}

这是UDPManager。当System.out.println正确显示“Received packet”时,数据包被正确传输到管理器并且阵列的大小确实增加了。我遇到的问题是,在“run()”中,它看不到大小增加。奇怪的是,它在调试中工作得非常好。知道它为什么会这样吗?

非常感谢您的帮助。

共有2个答案

干子瑜
2023-03-14

您应该在访问或修改数据包时对其进行同步

仲高超
2023-03-14

问题是,您的第一个线程正在将新数据放入数据包变量中,但对于第二个线程,这是不可见的。您应该同步对数组的访问。

当您启动第二个线程时,所有变量都会被复制。第二个线程只处理副本。您需要同步对该变量的访问,以便其他线程可以看到更改。

 类似资料:
  • 我正在运行一个记录的测试计划。我在线程组中分配了5个不同的用户,上升周期为5,循环计数为1。 这就是发生的情况: 开始测试。 测试运行没有错误,并且当我在视图结果树中检查时,似乎5个用户正确执行,但当我在系统中检查时,只有2或3个用户注册。我删除注册的用户,并运行脚本一次又一次的2或3个用户注册(有些时间不一样)的5个用户。 我不明白怎么会让我的测试表现得那样...为什么我的测试计划没有为5个用户

  • 当我编译并运行StartThreads类时,我会得到一个包含1到1000000的整数列表,其中包含false,最后显示true;现在我想弄清楚的是,为什么threadone类应该打印一次MyVariables类中的实例变量时却什么也不打印?公共类MyVariables{public boolean startApp=false;}

  • 问题内容: 有谁知道是否有一种方法可以动态地(运行时)增加主线程的堆栈大小?另外,我相信这是同样的问题,是否可以在实例化之后增加/更新a的堆栈大小? 的CTOR允许定义其堆栈大小,但是我找不到任何更新方法。实际上,我没有在JDK中找到对堆栈大小的任何管理(这往往表明这是不可能的),一切都在VM中完成。 根据Java语言规范,可以在“创建堆栈时”设置堆栈大小,但需要注意以下几点: Java虚拟机实现

  • 我是jmeter的新手,尝试对我的应用程序进行性能测试。我想每秒生成100个请求,但是我的服务器需要3-4秒来响应每个请求。我正在运行1分钟的测试,这意味着在时间跨度内激发的请求数应该是60k。然而,jmeter实际上在发送下一个请求之前等待响应。这不是我要找的。 我如何确保jmeter每秒发送一个新的请求(100 req/sec),而不等待响应,这样每分钟触发的请求数就是60k。 我尝试使用恒定

  • 问题内容: 我不能在具有15G内存的Linux机器中创建超过32k个Java线程。 问题答案: 您可以使用示例程序来找出当前的线程限制。 如果遇到,请检查以下内容: 在小型内存机器中 每个Java线程都消耗自己的堆栈内存。默认堆栈大小为1024k(= 1M)。您可以像这样减少堆栈大小。如果堆栈太小,则无法启动JVM。 并且要注意堆内存配置:(初始)和(最大)。分配给堆的内存越多,堆栈可用的内存就越

  • 我一直在研究一个深度学习库,自己写作。在矩阵运算中,获得最佳性能对我来说是一个关键。我一直在研究编程语言及其对数字运算的性能。过了一段时间,我发现C#SIMD具有与C++SIMD非常相似的性能。所以,我决定用C#编写这个库。 首先,我测试了C#SIMD(我测试了很多东西,但是这里不写了)。我注意到,当使用较小的数组时,它的工作效果要好得多。当使用较大的数组时,效率不高。我觉得很可笑。通常情况下,当