Use*_*er3 1 java multithreading
我有一个有数十亿条记录的ArrayList,我遍历每条记录并将其发布到服务器.在每次迭代中调用如下方法:
public void sendNotification(String url, String accountId, String accountPwd, String jsonPayLoad,
int maxConnections) {
notificationService = Executors.newFixedThreadPool(maxConnections);
notificationService.submit(new SendPushNotification(url, accountId, accountPwd, jsonPayLoad));
notificationService.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
我的SendPushNotification类如下:
public class SendPushNotification implements Runnable {
String url;
String accountId;
String accountPwd;
String jsonPayLoad;
public SendPushNotification(String url, String accountId, String accountPwd, String jsonPayLoad) {
this.url = url;
this.accountId = accountId;
this.accountPwd = accountPwd;
this.jsonPayLoad = jsonPayLoad;
}
public void run() {
HttpsURLConnection conn = null;
try {
StringBuffer response;
URL url1 = new URL(url);
conn = (HttpsURLConnection) url1.openConnection();
// conn.setReadTimeout(20000);
// conn.setConnectTimeout(30000);
conn.setRequestProperty("X-Account-Id", accountId);
conn.setRequestProperty("X-Passcode", accountPwd);
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
writer.write(jsonPayLoad);
writer.close();
out.close();
int responseCode = conn.getResponseCode();
System.out.println(String.valueOf(responseCode));
switch (responseCode) {
case 200:
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
} catch (IOException ez) {
ez.printStackTrace();
} finally {
if (conn != null) {
try {
conn.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以这里出了什么问题,我怀疑我必须在一个不错的系统配置上运行它.基本上我想知道我的代码是否有任何问题?
错误的做法!循环:
notificationService = Executors.newFixedThreadPool(maxConnections);
Run Code Online (Sandbox Code Playgroud)
是个坏主意!为什么要打造数十亿个ThreadPools; 提交一个任务然后关闭它?!这就像每次灰盘都满了就买一辆新法拉利......
请理解:您的简单代码会创建大量对象; 并且所有这些都在一次循环迭代后消失.含义:他们有资格进行垃圾收集.换句话说:你经常以非常高的速度创造垃圾.你真的很惊讶,这样做会让你陷入"记忆力不足"的境地吗?
相反,使用一个 ThreadPool并将您的数十亿请求提交给它!
除此之外,即使这不是一个好主意.每个条目打开一个到您服务器的网络连接,根本不会扩展到数十亿条目:一个真正的解决方案要求您退后一步,思考一些以"合理的方式"端到端工作的东西.例如,您应该考虑在服务器上创建某种"批量"或"流式"接口.迭代客户端上的数十亿条目文件,并与服务器建立数十亿的连接很遗憾,疯了!
所以不要这样做:
loop:
open connection / push ONE item / close connection
Run Code Online (Sandbox Code Playgroud)
你最好去:
open connection / push all items / close connections
Run Code Online (Sandbox Code Playgroud)
除此之外,您甚至可以研究传输压缩的二进制数据.含义:在客户端压缩文件,将其作为blob发送; 并在服务器端提取/处理它.
这里有很多选择空间; 但请放心:您当前的"内存不足"异常仅仅是由"不合适"设计引起的一种症状.
编辑:鉴于您的意见,我的(个人)建议:
| 归档时间: |
|
| 查看次数: |
1225 次 |
| 最近记录: |