Java 采用消费生产者设计的TCP套接字服务器';超过cpu时间限制';

Java 采用消费生产者设计的TCP套接字服务器';超过cpu时间限制';,java,multithreading,sockets,concurrency,producer-consumer,Java,Multithreading,Sockets,Concurrency,Producer Consumer,当运行使用消费者/生产者设计创建的套接字服务器时出现此问题,程序崩溃,日志中出现错误cpu时间限制超限。我还发现当时cpu的使用率超过90%。这是服务器的代码,它可能出了什么问题,我如何优化它 我使用这种队列方法来避免为每个请求创建如此多的线程 主方法(主线程) //保存套接字实例 ConcurrentLinkedQueue=新建ConcurrentLinkedQueue(); //创建生产者线程 线程生产者=新线程(新请求生产者(队列)); //创建消费线程 线程消费者=新线程(新请求消费者(

当运行使用消费者/生产者设计创建的套接字服务器时出现此问题,程序崩溃,日志中出现错误
cpu时间限制超限。我还发现当时
cpu
的使用率超过
90%
。这是服务器的代码,它可能出了什么问题,我如何优化它

我使用这种
队列
方法来避免为每个请求创建如此多的
线程

主方法(主线程)

//保存套接字实例
ConcurrentLinkedQueue=新建ConcurrentLinkedQueue();
//创建生产者线程
线程生产者=新线程(新请求生产者(队列));
//创建消费线程
线程消费者=新线程(新请求消费者(队列));
producer.start();
consumer.start();
RequestProducer线程

//holds socket instances
ConcurrentLinkedQueue<Socket> queue = new ConcurrentLinkedQueue<>();

//create producer thread
Thread producer = new Thread(new RequestProducer(queue));
//create consumer thread
Thread consumer = new Thread(new RequestConsumer(queue));

producer.start();
consumer.start();
//this holds queue instance coming from main thread
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestProducer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        //create serversocket instance on port 19029
        ServerSocket serverSocket = new ServerSocket(19029);
        while (true) {
            try {
                //keep accept connections
                Socket socket = serverSocket.accept();
                //add socket to queue
                queue.offer(socket);
            } catch (ConnectException ce) {//handle exception
            } catch (SocketException e) {//handle exception
            }
        }
    } catch (IOException ex) {//handle exception}
}
//this holds queue instance coming from main thread, same as requestproducer
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestConsumer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        Socket socket = null;
        while (true) {
            //get head of the queue (socket instance)
            socket = queue.poll();
            if (null != socket) {
                //process data stream
                String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                //close socket conection
                socket.close();
                //excecute database insert of processed data
                excecuteDbInsert(in);
            }
        }
    } catch (IOException | ParseException ex) {//handle exceptions}
}
import java.io.IOException;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestProducer implements Runnable {
    //this holds queue instance coming from main thread
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestProducer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            //create serversocket instance on port 19029
            ServerSocket serverSocket = new ServerSocket(19029);
            while (true) {
                try {
                    //keep accept connections
                    Socket socket = serverSocket.accept();
                    //add socket to queue
                    queue.offer(socket);
                    synchronized (queue) {
                        System.out.println("notifying");
                        queue.notify();
                    }
                } catch (ConnectException ce) {//handle exception
                } catch (SocketException e) {//handle exception
                }
            }
        } catch (IOException ex) {//handle exception}
        }

    }
}
import java.io.IOException;
import java.net.Socket;
import java.text.ParseException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestConsumer implements Runnable {
    //this holds queue instance coming from main thread, same as requestproducer
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestConsumer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            Socket socket = null;
            while (true) {
                //get head of the queue (socket instance)
                System.out.println("Waiting for new socket");
                synchronized (queue) {
                    queue.wait();
                }
                System.out.println("Acquired new socket");

                socket = queue.poll();
                try {
                    if (null != socket) {
                        //process data stream
                        String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                        //close socket conection
                        socket.close();
                        //excecute database insert of processed data
                        //excecuteDbInsert(in);

                        System.out.println(in);
                    }
                } finally {
                    if (socket != null) {
                        socket.close();
                    }
                }

            }
        } catch (IOException ex) {//handle exceptions}
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

}
//它保存来自主线程的队列实例
ConcurrentLinkedQueue队列
//构造函数,初始化队列
公共生产者(
ConcurrentLinkedQueue队列
) {
this.queue=队列;
}
公开募捐{
试一试{
//在端口19029上创建serversocket实例
ServerSocket ServerSocket=新的ServerSocket(19029);
while(true){
试一试{
//保持并接受连接
Socket=serverSocket.accept();
//将套接字添加到队列
队列。提供(套接字);
}catch(ConnectException){//handle异常
}catch(SocketException e){//句柄异常
}
}
}catch(IOException ex){//handle exception}
}
请求消费者线程

//holds socket instances
ConcurrentLinkedQueue<Socket> queue = new ConcurrentLinkedQueue<>();

//create producer thread
Thread producer = new Thread(new RequestProducer(queue));
//create consumer thread
Thread consumer = new Thread(new RequestConsumer(queue));

producer.start();
consumer.start();
//this holds queue instance coming from main thread
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestProducer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        //create serversocket instance on port 19029
        ServerSocket serverSocket = new ServerSocket(19029);
        while (true) {
            try {
                //keep accept connections
                Socket socket = serverSocket.accept();
                //add socket to queue
                queue.offer(socket);
            } catch (ConnectException ce) {//handle exception
            } catch (SocketException e) {//handle exception
            }
        }
    } catch (IOException ex) {//handle exception}
}
//this holds queue instance coming from main thread, same as requestproducer
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestConsumer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        Socket socket = null;
        while (true) {
            //get head of the queue (socket instance)
            socket = queue.poll();
            if (null != socket) {
                //process data stream
                String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                //close socket conection
                socket.close();
                //excecute database insert of processed data
                excecuteDbInsert(in);
            }
        }
    } catch (IOException | ParseException ex) {//handle exceptions}
}
import java.io.IOException;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestProducer implements Runnable {
    //this holds queue instance coming from main thread
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestProducer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            //create serversocket instance on port 19029
            ServerSocket serverSocket = new ServerSocket(19029);
            while (true) {
                try {
                    //keep accept connections
                    Socket socket = serverSocket.accept();
                    //add socket to queue
                    queue.offer(socket);
                    synchronized (queue) {
                        System.out.println("notifying");
                        queue.notify();
                    }
                } catch (ConnectException ce) {//handle exception
                } catch (SocketException e) {//handle exception
                }
            }
        } catch (IOException ex) {//handle exception}
        }

    }
}
import java.io.IOException;
import java.net.Socket;
import java.text.ParseException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestConsumer implements Runnable {
    //this holds queue instance coming from main thread, same as requestproducer
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestConsumer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            Socket socket = null;
            while (true) {
                //get head of the queue (socket instance)
                System.out.println("Waiting for new socket");
                synchronized (queue) {
                    queue.wait();
                }
                System.out.println("Acquired new socket");

                socket = queue.poll();
                try {
                    if (null != socket) {
                        //process data stream
                        String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                        //close socket conection
                        socket.close();
                        //excecute database insert of processed data
                        //excecuteDbInsert(in);

                        System.out.println(in);
                    }
                } finally {
                    if (socket != null) {
                        socket.close();
                    }
                }

            }
        } catch (IOException ex) {//handle exceptions}
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

}
//它保存来自主线程的队列实例,与requestproducer相同
ConcurrentLinkedQueue队列
//构造函数,初始化队列
公共消费者(
ConcurrentLinkedQueue队列
) {
this.queue=队列;
}
公开募捐{
试一试{
套接字=空;
while(true){
//获取队列头(套接字实例)
socket=queue.poll();
if(null!=套接字){
//处理数据流
字符串in=DataStreamUtil.parseAscioIsockstream(socket.getInputStream());
//闭合插座连接
socket.close();
//已处理数据的异常数据库插入
例外宾塞特(in);
}
}
}catch(IOException | ParseException ex){//handle exceptions}
}
数据流解析器

public static String parseAsciiSockStream(InputStream in) throws IOException {
    StringBuilder builder = new StringBuilder();
    if (null != in) {
        byte[] b = new byte[BYTE_STREAM_MAX];
        int length = in.read(b);
        for (int i = 0; i < length; i++) {
            builder.append((char) (int) b[i]);
        }
        in.close();
    }
    return builder.toString();
}
import java.io.IOException;
import java.io.InputStream;

public class DataStreamUtil {
    public static String parseAsciiSockStream(InputStream in) throws IOException {
        StringBuilder builder = new StringBuilder();
        if (null != in) {
            byte[] b = new byte[BYTE_STREAM_MAX];
            System.out.println("Waiting for input");
            int length = in.read(b);
            System.out.println("Got input");
            for (int i = 0; i < length; i++) {
                builder.append((char) (int) b[i]);
            }
            in.close();
        }
        return builder.toString();
    }
}
public静态字符串parseAsciisoCstream(InputStream-in)引发IOException{
StringBuilder=新的StringBuilder();
如果(null!=in){
byte[]b=新字节[byte_STREAM_MAX];
整数长度=英寸读数(b);
for(int i=0;i
由于恶意
while(true)
循环进入消费者,超出了CPU时间限制。下面是一个如何解决问题的示例

您可以在while循环中将simple
Thread.sleep(1)
添加到使用者中,或者使用wait/notify模式来限制CPU消耗

RequestProducer线程

//holds socket instances
ConcurrentLinkedQueue<Socket> queue = new ConcurrentLinkedQueue<>();

//create producer thread
Thread producer = new Thread(new RequestProducer(queue));
//create consumer thread
Thread consumer = new Thread(new RequestConsumer(queue));

producer.start();
consumer.start();
//this holds queue instance coming from main thread
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestProducer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        //create serversocket instance on port 19029
        ServerSocket serverSocket = new ServerSocket(19029);
        while (true) {
            try {
                //keep accept connections
                Socket socket = serverSocket.accept();
                //add socket to queue
                queue.offer(socket);
            } catch (ConnectException ce) {//handle exception
            } catch (SocketException e) {//handle exception
            }
        }
    } catch (IOException ex) {//handle exception}
}
//this holds queue instance coming from main thread, same as requestproducer
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestConsumer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        Socket socket = null;
        while (true) {
            //get head of the queue (socket instance)
            socket = queue.poll();
            if (null != socket) {
                //process data stream
                String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                //close socket conection
                socket.close();
                //excecute database insert of processed data
                excecuteDbInsert(in);
            }
        }
    } catch (IOException | ParseException ex) {//handle exceptions}
}
import java.io.IOException;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestProducer implements Runnable {
    //this holds queue instance coming from main thread
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestProducer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            //create serversocket instance on port 19029
            ServerSocket serverSocket = new ServerSocket(19029);
            while (true) {
                try {
                    //keep accept connections
                    Socket socket = serverSocket.accept();
                    //add socket to queue
                    queue.offer(socket);
                    synchronized (queue) {
                        System.out.println("notifying");
                        queue.notify();
                    }
                } catch (ConnectException ce) {//handle exception
                } catch (SocketException e) {//handle exception
                }
            }
        } catch (IOException ex) {//handle exception}
        }

    }
}
import java.io.IOException;
import java.net.Socket;
import java.text.ParseException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestConsumer implements Runnable {
    //this holds queue instance coming from main thread, same as requestproducer
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestConsumer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            Socket socket = null;
            while (true) {
                //get head of the queue (socket instance)
                System.out.println("Waiting for new socket");
                synchronized (queue) {
                    queue.wait();
                }
                System.out.println("Acquired new socket");

                socket = queue.poll();
                try {
                    if (null != socket) {
                        //process data stream
                        String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                        //close socket conection
                        socket.close();
                        //excecute database insert of processed data
                        //excecuteDbInsert(in);

                        System.out.println(in);
                    }
                } finally {
                    if (socket != null) {
                        socket.close();
                    }
                }

            }
        } catch (IOException ex) {//handle exceptions}
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

}
import java.io.IOException;
导入java.net.ConnectException;
导入java.net.ServerSocket;
导入java.net.Socket;
导入java.net.SocketException;
导入java.util.concurrent.ConcurrentLinkedQueue;
公共类RequestProducer实现了Runnable{
//这将保存来自主线程的队列实例
最终ConcurrentLinkedQueue队列;
//构造函数,初始化队列
公共生产者(
ConcurrentLinkedQueue队列
) {
this.queue=队列;
}
公开募捐{
试一试{
//在端口19029上创建serversocket实例
ServerSocket ServerSocket=新的ServerSocket(19029);
while(true){
试一试{
//保持并接受连接
Socket=serverSocket.accept();
//将套接字添加到队列
队列。提供(套接字);
已同步(队列){
System.out.println(“通知”);
queue.notify();
}
}catch(ConnectException){//handle异常
}catch(SocketException e){//句柄异常
}
}
}catch(IOException ex){//handle exception}
}
}
}
请求消费者线程

//holds socket instances
ConcurrentLinkedQueue<Socket> queue = new ConcurrentLinkedQueue<>();

//create producer thread
Thread producer = new Thread(new RequestProducer(queue));
//create consumer thread
Thread consumer = new Thread(new RequestConsumer(queue));

producer.start();
consumer.start();
//this holds queue instance coming from main thread
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestProducer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        //create serversocket instance on port 19029
        ServerSocket serverSocket = new ServerSocket(19029);
        while (true) {
            try {
                //keep accept connections
                Socket socket = serverSocket.accept();
                //add socket to queue
                queue.offer(socket);
            } catch (ConnectException ce) {//handle exception
            } catch (SocketException e) {//handle exception
            }
        }
    } catch (IOException ex) {//handle exception}
}
//this holds queue instance coming from main thread, same as requestproducer
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestConsumer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        Socket socket = null;
        while (true) {
            //get head of the queue (socket instance)
            socket = queue.poll();
            if (null != socket) {
                //process data stream
                String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                //close socket conection
                socket.close();
                //excecute database insert of processed data
                excecuteDbInsert(in);
            }
        }
    } catch (IOException | ParseException ex) {//handle exceptions}
}
import java.io.IOException;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestProducer implements Runnable {
    //this holds queue instance coming from main thread
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestProducer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            //create serversocket instance on port 19029
            ServerSocket serverSocket = new ServerSocket(19029);
            while (true) {
                try {
                    //keep accept connections
                    Socket socket = serverSocket.accept();
                    //add socket to queue
                    queue.offer(socket);
                    synchronized (queue) {
                        System.out.println("notifying");
                        queue.notify();
                    }
                } catch (ConnectException ce) {//handle exception
                } catch (SocketException e) {//handle exception
                }
            }
        } catch (IOException ex) {//handle exception}
        }

    }
}
import java.io.IOException;
import java.net.Socket;
import java.text.ParseException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class RequestConsumer implements Runnable {
    //this holds queue instance coming from main thread, same as requestproducer
    final ConcurrentLinkedQueue<Socket> queue;

    //constructor, initiate queue
    public RequestConsumer(
            ConcurrentLinkedQueue<Socket> queue
    ) {
        this.queue = queue;
    }

    public void run() {
        try {
            Socket socket = null;
            while (true) {
                //get head of the queue (socket instance)
                System.out.println("Waiting for new socket");
                synchronized (queue) {
                    queue.wait();
                }
                System.out.println("Acquired new socket");

                socket = queue.poll();
                try {
                    if (null != socket) {
                        //process data stream
                        String in = DataStreamUtil.parseAsciiSockStream(socket.getInputStream());
                        //close socket conection
                        socket.close();
                        //excecute database insert of processed data
                        //excecuteDbInsert(in);

                        System.out.println(in);
                    }
                } finally {
                    if (socket != null) {
                        socket.close();
                    }
                }

            }
        } catch (IOException ex) {//handle exceptions}
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

}
import java.io.IOException;
导入java.net.Socket;
导入java.text.ParseException;
导入java.util.concurrent.ConcurrentLinkedQueue;
公共类RequestConsumer实现可运行{
//这将保存来自主线程的队列实例,与requestproducer相同
最终ConcurrentLinkedQueue队列;
//构造函数,初始化队列
公共消费者(
ConcurrentLinkedQueue队列
) {
this.queue=队列;
}
公开募捐{
试一试{
套接字=空;
while(true){
//获取队列头(套接字实例)
System.out.println(“等待新套接字”);
已同步(队列){
queue.wait();
}
System.out.println(“获得的新套接字”);
socket=queue.poll();
试一试{
if(null!=套接字){
//处理数据流
字符串in=DataStreamUtil.parseAscioIsockstream(socket.getInputStream());
//闭合插座连接
socket.close();
//已处理数据的异常数据库插入
//多余的箱子