Java小白急求大神指教。

//启动Receive线程
public class Demo2 {
public static void main(String[] args) {
Receive receive = Receive.getConstructor();

    new Thread(receive).start();
}

}

//Receive线程类   服务端

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

class Receive implements Runnable{

    private final int port = 22222;
    private static InetAddress localHost;
    private static volatile SocketAddress socketAddress;
    private static volatile Scanner scanner = new Scanner(System.in);
    private static volatile boolean send = true;
    private static Receive receive;
    private static Thread thread;

    static {
        try {
            localHost = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    static volatile DatagramSocket socket = null;
    {
        try {
            socket =new DatagramSocket(port, localHost);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    private Receive(){}
    static Receive getConstructor(){
        if(socket == null){
            receive = new Receive();
            thread = new Thread(receive, "send");
            thread.setDaemon(true);
            return receive;
        }
        return receive;
    }


    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        if(name.equals("send")){
            send();
        }else {
            receive();
        }
    }

        //发送消息方法
    public static void send()  {
        DatagramPacket sendPacket = null;
        byte[] sendByte = new byte[1024];
        String sendMiss = null;
        sendPacket = new DatagramPacket(sendByte, sendByte.length, socketAddress);

        while (send){
            sendMiss = scanner.next();
            //scanner.close();
            sendByte = sendMiss.getBytes();
            sendPacket.setData(sendByte);

            try {
                socket.send(sendPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
        //接收消息方法
    public static void receive(){
        DatagramPacket receivePacket = null;
        byte[] receiveByte = new byte[1024];
        String string = null;
        receivePacket = new DatagramPacket(receiveByte, receiveByte.length);
        int i = 0;
        System.out.println("服务端已启动。。。");
        while (send){
            try {
                socket.receive(receivePacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
            socketAddress = receivePacket.getSocketAddress();
            if(i == 0){
                thread.start();
                i = 1;
            }
            int length = receivePacket.getLength();
            string = new String(receiveByte, 0, length);
            if(string.equals("exit")){
                socket.close();
                send = false;
                //scanner.close();
                //threradStop();
                System.out.println("服务端已关闭通信");
            }else{
                System.out.println("服务端接受到的消息是:" + string);
            }

        }

    }
}

//用来启动Send线程类
public class Demo {
public static void main(String[] args) {
Send send = new Send();

    new Thread(send, "send").start();
    new Thread(send).start();

}

}

//Send线程类  客户端

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

class Send implements Runnable{
    final int port = 11001;
    static InetAddress localHost;

    static {
        try {
            localHost = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    static DatagramSocket socket;

    {
        try {
            socket = new DatagramSocket(port, localHost);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    static Scanner scanner = new Scanner(System.in);
    static volatile boolean send = true;
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        if(name.equals("send")){
            send();
        }else {
            receive();
        }
    }

        //发送消息方法
    private static void send(){
        DatagramPacket sendPacket = null;
        byte[] sendByte = new byte[1024];

        try{
        while(send){
            sendPacket = new DatagramPacket(sendByte, sendByte.length, localHost, 22222);
            String sendString = scanner.nextLine();
            if(sendString.equals("exit")){

                sendByte = sendString.getBytes();
                sendPacket.setData(sendByte);
                //System.out.println(Arrays.toString(sendByte));
                socket.send(sendPacket);

                scanner.close();
                socket.close();
                send = false;
            }else{
                sendByte = sendString.getBytes();
                sendPacket.setData(sendByte);
                //System.out.println(Arrays.toString(sendByte));
                socket.send(sendPacket);
            }

        }

    } catch (SocketException | UnknownHostException e) {
        e.printStackTrace();
    } catch (
    IOException e) {
        e.printStackTrace();
    }
    }

        //接收消息方法
    private static void receive(){
        DatagramPacket receivePacket = null;
        byte[] receiveByte = new byte[1024];
        String receiveMiss = null;
        receivePacket = new DatagramPacket(receiveByte, receiveByte.length);

        try {
            while (!socket.isClosed()){


                socket.receive(receivePacket);   //这里是88行,等待接收


                receiveMiss = new String(receiveByte);
                System.out.println("客户端接收到的消息是:" + receiveMiss);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

图片说明

在UDP中两个线程公用一个socket,一个线程等待接收数据堵塞,另一个线程关闭socket,就会报出图片上的错误,前面是我写的代码,这个问题怎么解决,求指教。。。如果对代码有指教,请指教。。。

试试关闭socket的时候把那个阻塞的线程一起关了,或者在接受消息的方法(那个阻塞线程)里关闭socket