一种多线程设计思路
2021-06-26 20:07
标签:lap common 还需要 fast 异步 zed set pre cli 举个例子说明多线程的作用。比如有100个人去食堂打菜,如果只有一个窗口,那么所有人都需要在这个窗口进行排队,一个打完才能排到下一个,如果每个人打菜需要1分钟,这100个人打完菜总耗时就是100分钟,这就类似程序中的单线程。如果有5个打菜窗口,那么就可以每次5个人几乎同时进行打菜,相当于把100个人分成5个队,这样打菜的时间就减少了5倍,这100个人打完菜总耗时差不多为20分钟。这就类似于程序中使用了多线程。所以,使用多线程对用户体验的提升毋庸置疑。 类似,物业软件中也有很多场景可以使用多线程。如多线程远程开门(同时开整个小区所有的门)、多线程下载卡、多线程下载设备参数、多线程删除卡等。 本文旨在设计一个通用型的多线程Http客户端。既然是通用,肯定是要兼容各种数据类型,而json字符串恰好能承担这个重任。另一方面,几乎所有的业务执行都需要得到执行结果反馈,故多线程的设计还需要考虑业务上的阻塞。这篇多线程程序阻塞核心算法如下: 从上述程序可看出,多线程的创建及执行使用了线程池做管理,而ExecutorService中的shutdown和isTerminated方法结合起来就可以实现多线程阻塞。 其次,对于某些多线程业务,可能还需要依赖外部资源。如物业软件的门禁记录转发,由于设备门禁记录和抓拍的图片数据是异步上传的,通常记录会先到,抓拍的图片会延迟一两秒才上报完成。而转发给第三方的门禁数据中需要包含抓拍图片,那怎么办呢?本文同样提供了解决办法,如下: (1)转发门禁记录时,使用LockUtil的lock方法(key为图片路径)将转发线程锁住。 (2)图片数据上报到物业中心时,先使用LockUtil的setParam方法把图片数据设置到缓存中,再使用LockUtil的unlock方法(key为图片路径)将图片解锁。 (3)解锁后的门禁记录线程,使用LockUtil的getParma方法把图片数据从缓存中读出来,并添加到记录的属性中,就可了转发一条完整的门禁记录到第三方了。 核心算法如下: 上述设计方法看似已经没什么问题,其实不然,由于应答数据是从多线程中逐条添加的,并且使用了ArrayList,而ArrayList是线程不安全的(ArrayList线程为什么不安全,请移步到https://blog.csdn.net/u012859681/article/details/78206494)。要解决ArrayList的线程安全问题其实很简单,只需要将多线程中的ArrayList改成如下写法即可: 一种多线程设计思路 标签:lap common 还需要 fast 异步 zed set pre cli 原文地址:https://www.cnblogs.com/helloworldplus/p/9655638.html一、为什么设计多线程
二、多线程的设计思路
public List
@Override
public void run() {
super.run();
// 若线程有锁,此处处理线程锁中的参数。
if (hasLock) {
// 使用LockUtil的lock方法(key为图片路径)将转发线程锁住
LockUtil.getInstance().lock(lockKey, 20);
// 使用LockUtil的getParma方法把图片数据从缓存中读出来
String param = (String)LockUtil.getInstance().getParam(lockKey);
// 把参数添加到记录的属性中
if (StringUtils.isNotBlank(param)) {
JSONObject obj = JSON.parseObject(data);
obj.put(lockParamKey, param);
data = JSON.toJSONString(obj);
}
}
String res = HttpRequest.post(url).body(data).execute().body();
jsonArrayResponse.add(res);
}
List
三、程序摘要
package com.leelen.ehome.multithread;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.leelen.ehome.utils.LockUtil;
import com.xiaoleilu.hutool.http.HttpRequest;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Http多线程客户端
*
* @Author:Jack
*/
public class HttpMultithreadClient {
/**
* json字符串数组,即需要发送的数据。
*/
private List