简体   繁体   中英

Why are my Java threads not running at the same time?

I have an application that is communicating with a UDP server. My application listens on one port (say 1234) and sends on another (say 5678). The UDP server I am communicating with also requires a "heartbeat" ever 5 seconds, for which I create another thread. When my application first starts up, I create the listen thread, then create the heartbeat thread, then I start sending the UDP server message packets. The only thing, however, is that it seems like all the packets I send out finish before the heartbeat thread starts.

Here is what I have for my listener:

public class MyListener implements Runnable {
    private volatile boolean run = true;
    private DatagramSocket myDatagramSocket;
    private DatagramPacket myDatagramPacket;
    private byte[] receiveBuffer;
    private int receiveBufferSize;

    @Override
    public void run(){
        while(run){
            try {
                myDatagramSocket = new DatagramSocket(null);
                InetSocketAddress myInetSocketAddress = new InetSocketAddress(1234);
                myDatagramSocket.bind(myInetSocketAddress);

                receiveBuffer = new byte[2047];
                myDatagramPacket = new DatagramPacket(receiveBuffer, 2047);

                myDatagramSocket.receive(myDatagramPacket);
                byte[] data = myDatagramPacket.getData();

                receiveBufferSize = myDatagramPacket.getLength();

                switch(messageID){
                    ...
                }
            } catch (Exception e){
            }
        }
    }
}

Here is what I have for my heartbeat:

public class MyHeartbeat implements Runnable {
    private volatile boolean run = true;
    private HeartbeatSenderClass heartbeatSender;

    @Override
    public void run(){
        while(run){
            try {
                TimeUnit.SECONDS.sleep(5);
                heartbeatSender.sendHeartbeat();
            } catch(Exception e){
            }
        }
    }
}

Here is what I have for my main class:

public class MyApp {
    public static void main(String[] args){
        MyListener listener = new MyListener();
        Thread listenerThread = new Thread(listener);
        listenerThread.setName("Listener Thread");
        listenerThread.start();

        MyHeartbeat heartbeat = new MyHeartbeat();
        Thread heartbeatThread = new Thread(heartbeat);
        heartbeatThread.setName("Heartbeat Thread");
        heartbeatThread.start();

        MySender sender = new MySender();
        Thread senderThread = new Thread(sender);
        senderThread.setName("Sender Thread");
        senderThread.start();
    }
}

All of my packets are making it to the UDP server, but not smoothly like I would have thought. I would have thought that while I am sending packets to the server, every 5 seconds my heartbeat would be sent out. However, it seems like my heartbeats are going out only after my packets are done sending. Also, I believe I am not getting all of the messages from the UDP server. I say this because I have sniffed the UDP packets on my machine and I see data coming from the server that my receiver is not receiving/processing. Any suggestions?

You have in heartbeat this:

 TimeUnit.SECONDS.sleep(5);
 heartbeatSender.sendHeartbeat();

So before sending the very first beat, you wait for 5 seconds. No wonder that the other threads do their job meanwhile.

The DatagramSocket you use to send the packets is a shared resource that is contended between threads, and then if a thread consume too much of that resource, another one may starve. See: Thread starvation

Also if you are loosing packets, it happens because you can't read as fast as you should. If udp packets arrive faster then they can be read, the queue will discard the remaining.

Under linux, for example you can control the receive buffer with:

sudo sysctl -w net.core.rmem_default=26214400
sudo sysctl -w net.ipv4.udp_mem='26214400 26214400 26214400'
sudo sysctl -w net.ipv4.udp_rmem_min=26214400

But anyway if we are talking about a sustained loss, you should consider to have a thread for reading the buffer, a queue and a thread to process the readed data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM