gpt4 book ai didi

network-programming - 为什么Java的socket.connect()会占用100%的cpu资源?

转载 作者:搜寻专家 更新时间:2023-11-01 00:58:31 25 4
gpt4 key购买 nike

我创建了一个线程池并为其分配了 50 个任务来连接到服务器。所以一旦完成连接,发送一些数据,然后断开连接。它还将读取超时设置为 5 秒(当然是 5000 长)。我什至将线程池的最大大小设置为 1。然后我在 Linux 上启动它,并运行 htop(top 的更好版本)来检查 CPU 使用率。我一直看到我的一个核心(2 核机器)始终处于 100%。我使用 hprof (-agentlib:hprof=cpu=samples,interval=20,depth=3) 对此进行了分析,并且 socket.connect() 达到了 99%。

这就是我觉得奇怪的地方,阻塞 IO 的目的不是要阻塞(因此等待)吗?我的 JDK 是(来自 java -version):

OpenJDK 运行时环境 (IcedTea6 1.6.1) (6b16-1.6.1-3ubuntu3)

OpenJDK 服务器虚拟机(build 14.0-b16,混合模式)

Update1:同样的问题也发生在 Sun 的 JVM 上:

java -version
Java version "1.6.0_20"

Update2:这是由于 native 的 doConnect 方法。任何人都知道如何查看此 native /C 代码的源代码?

Update3:我登录到 windows 来编写代码并进行测试。它运行良好,没有占用 CPU 资源。我重新登录到 linux,现在问题仍然存在,但还没有严重到仅 1 个连接就以 100% 的速度控制整个 CPU 核心....这是代码:

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class SocketTest {


public static void main(String[] args) {
new SocketTest();

}

public SocketTest() {

ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(40);

Vector<Callable<Object>> tasks = new Vector<Callable<Object>>();

for (int i = 0; i < 1500; i++)
tpe.submit(new Thread() {

public void run() {
byte[] ip = { 74, 125, 19, (byte)((Math.random()*253)+1)};
Socket socket = new Socket();
try {
System.out.println("new thread: "+ip[3]);
socket.connect(new InetSocketAddress(InetAddress.getByAddress(ip), 80), 3000);
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
//no need to print
}
}
});

try {
tpe.invokeAll(tasks);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("test");
try {
//too lazy to write actual code to wait for task completness...
tpe.awaitTermination(9001, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test2");
}

}

最佳答案

我只是想评论一下,您似乎在滥用线程池,因为您实际上实例化了 Thread 类型的新对象 1500 次,只是为了将它们传递给实例化更多线程的线程池,以便运行您的任务。您通常应该做的是实例化一个 Runnable 并让线程池完成它的工作。我并不是说这是导致 CPU 阻塞的原因,但这确实是个问题。

关于network-programming - 为什么Java的socket.connect()会占用100%的cpu资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2978644/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com