注意:本文中没有请求ocr等例子,只是说明下java控制并发。
在开发中我们会碰到一些需要控制并发的情况,比如说我们请求外部接口时,外部接口不控制并发,需要我们自己控制并发。所以说本文说明一下自己的思路。
比如:
需要控制的并发是5(只能同时发5个请求,一个请求回来就再发一个,最多5个)
这个时候需要一个队列控制着并发
private static ConcurrentLinkedDeque<String> queue = new ConcurrentLinkedDeque<>();
话不多说上代码
import java.util.*;
import java.util.concurrent.ConcurrentLinkedDeque;
public class ConcurrentService {
private static final String AL_BABA_OCR_URL = "https://www.baidu.com";
public static final ConcurrentService me = new ConcurrentService();
/**
* 控制并发队列(要使用线程安全的队列)
*/
private static ConcurrentLinkedDeque<String> queue = new ConcurrentLinkedDeque<>();
static {
//把个数放进队列,要控制多少放到少,可以用别的方式我用的是这种
Collections.addAll(queue,
AL_BABA_OCR_URL,
AL_BABA_OCR_URL,
AL_BABA_OCR_URL,
AL_BABA_OCR_URL,
AL_BABA_OCR_URL);
}
/**
* 获取队列链接,获取不到等待控制并发数
*
* @param data
*/
public void getQueue(String data) {
HttpExecuteResponse response = null;
String url = "";
try {
while (true){
url = queue.poll();
//获取不到等待1S再次获取
if(url == null){
System.out.println("未获取到链接线程休眠");
// 调用sleep方法让当前线程暂停1S。
Thread.sleep(1000);
} else {
break;
}
}
System.out.println(data + "拿到了url:" + url);
//休眠2S 模拟真实操作(在这里写真实操作)
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}finally {
//不管成功失败都要吧拿出队列中的在放回队列中
queue.add(AL_BABA_OCR_URL);
}
}
public static void main(String[] args) throws InterruptedException {
//开50个线程测试
for (int i = 0; i < 50; i++) {
new Thread(() -> {
me.getQueue(UUID.randomUUID().toString());
}).start();
}
}
}