java - 守护进程线程数、线程数和总启动线程数

标签 java multithreading profiling jvisualvm

我有一个用 Java 编写的多线程回显服务器的简单代码(它将接收到的任何内容返回给客户端)。我正在分析服务器的各种资源,包括线程统计信息。以下是根据连接的客户端数量列出的一些统计数据。我的问题是与非基线相比的基线(# of clients 0)!

1) 为什么当单个客户端连接时,总线程数增加 2? (对于其余部分,增加 1 是有意义的)

2) 两个非守护线程是什么?!以及为什么守护进程最初增加 1 然后固定?

它们是随机的吗?!

# clients                    0  1   2   3   4   5   6   7   8   9   10

Total Started Thread Count  15  18  19  20  21  22  23  24  25  26  27
Thread count                14  16  17  18  19  20  21  22  23  24  25
Peak thread count           14  16  17  18  19  20  21  22  23  24  25
Daemon thread count         12  13  13  13  13  13  13  13  13  13  13

这是服务器的一段代码。我同时使用 RMI(供客户端轮询消息)和服务器套接字(供客户端发送消息)。如果需要其他类(class),请告诉我。

package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;

public class ServerRMI extends Thread implements Hello {
    //centralized token manager runs polling server and socket server to receive updated tokens
    static Vector<String> tokenList= new Vector<String>();
    protected Socket clientSocket;
    static int RMIRegistryPort=9001;
    static int SocketServerPort=9010;

    public static void main(String[] args) throws IOException {
        try {
            ServerRMI obj = new ServerRMI();
            Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.createRegistry(RMIRegistryPort);
            registry.bind("Hello", stub);
            System.err.println("Server ready");
        } catch (Exception e) {
            System.err.println("Server exception: " + e.toString());
            e.printStackTrace();
        }

        ServerSocket serverSocket = null;
        //initialize token list
        //A needs to execute first
        tokenList.add(0,"0");

        try {
            serverSocket = new ServerSocket(SocketServerPort);
            System.out.println("Connection Socket Created");
            try {
                while (true) {
                    System.out.println("Waiting for Connection");
                    new ServerRMI(serverSocket.accept());
                }
            } catch (IOException e) {
                System.err.println("Accept failed.");
            }
        } catch (IOException e) {
            System.err.println("Could not listen on port: "+SocketServerPort);
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("Could not close port: "+SocketServerPort);
            }
        }
    }

    private ServerRMI(Socket clientSoc) {
        clientSocket = clientSoc;
        start();
    }

    public ServerRMI() {}{
        // TODO Auto-generated constructor stub
    }

    public void run() {
        System.out.println("New Communication Thread Started");

        try {
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
                    true);
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    clientSocket.getInputStream()));

            String inputLine;

            while ((inputLine = in.readLine()) != null) {
                tokenList.add(0,inputLine);
                System.out.println("Server received: " + inputLine);
//                  System.out.println(" ququ size: "+queue.size());
                out.println(inputLine);

                if (inputLine.equals("Bye."))
                    break;
            }

            out.close();
            in.close();
            clientSocket.close();
        } catch (IOException e) {
            System.err.println("Problem with Communication Server");
        }
    }

    public String pollServer() {
        if(!tokenList.isEmpty()){
            String data = tokenList.get(0);
            System.out.println("Poll data: "+data);
            return data;
        } else{
            return tokenList.size()+"";
        }
    }
}

最佳答案

我不确定你用什么来接收这些连接,但通常处理 TCP 连接的框架是非阻塞的,比如 Netty使用主线程来监听端口和线程池来处理传入的连接。这意味着如果线程池限制为 1 个线程,它将至少为传入连接打开 2 个线程。

查看此 example来自 netty 页面,其中在引导服务器时使用了 2 个 NioEventLoopGroup。

这 2 个线程是不阻塞传入流量所必需的。

关于java - 守护进程线程数、线程数和总启动线程数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37154657/

相关文章:

Python:如何分析使用 numba.njit() 装饰器编写的代码

Java 比较数组中的字符串

python - 使用 statprof 分析 Django View - 不能在线程中使用信号

java - 并发解谜: Java Concurrency - Cyclicbarrier. 正确用法?

java - Java中的优先级信号量

c# - 多线程翻译

c++ - cpp中的pthread用于类中的不同成员函数

java - Android GPU 分析 - OpenGL 动态壁纸很慢

java - 变量定义在外循环和内循环之间有区别吗?

java - 我们已使用android Studio并遇到此错误