一段簡單程式碼理解非同步請求訊息佇列在高併發環境中的作用
普通同步方法被呼叫模擬
package top.yuyufeng.mq;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by yuyufeng on 2017/8/29.
*/
public class MyServer {
private static AtomicInteger atomicInteger = new AtomicInteger(1);
public static void createOrder(String product) {
int res = atomicInteger.getAndIncrement();
if (res >= 10) {
System.err.println("超過當前容量(10) " + res);
}
System.out.println(product + "當前正在處理的執行緒數 " + res);
doJob();
atomicInteger.getAndDecrement();
}
private static void doJob() {
Random random = new Random();
long sleepTime = random.nextInt(10) * 100;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//模擬發起請求 併發一旦上去,就會超過限制大小,有當機危險
for (int i = 0; i < 12; i++) {
new Thread() {
@Override
public void run() {
for (int j = 0; j < 10; j++) {
MyServer.createOrder(Thread.currentThread().getName());
}
System.out.println(Thread.currentThread().getName() + "結束:" + atomicInteger);
}
}.start();
}
}
}
執行這段程式碼之後,你會看到,併發一單上去,當前處理的程式會超過額定容量(這裡設定為最高能應對10個程式同時處理,超過會卡頓)
應用訊息佇列後,變成非同步請求
package top.yuyufeng.mq;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by yuyufeng on 2017/8/29.
*/
public class MyServerByQuene {
private static AtomicInteger atomicInteger = new AtomicInteger();
//這裡使用jdk佇列,代替常用的訊息佇列服務
private static Queue<String> queue = new ConcurrentLinkedQueue<>();
private static ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(10);
public static void createOrder(String product) {
queue.add(product);
}
static {
//10個程式阻塞處理請求
for (int i = 0; i < 10; i++) {
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
while (true) {
String product = queue.poll();
if (product != null) {
int res = atomicInteger.getAndIncrement();
if (res >= 10) {
System.err.println("超過當前容量(10) " + res);
}
System.out.println(product + "當前正在處理的執行緒數 " + res);
doJob();
atomicInteger.getAndDecrement();
} else {
try {
Thread.sleep(1000);
System.out.println("MyServerByQuene.run 正在監聽...當前程式數量: " + atomicInteger);
} catch (InterruptedException e) {
}
}
}
}
});
}
}
private static void doJob() {
Random random = new Random();
long sleepTime = random.nextInt(10) * 100;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//模擬發起請求,這裡的併發更大 ,但是是非同步訊息佇列,會等待處理.能抗住高併發
for (int i = 0; i < 20; i++) {
new Thread() {
@Override
public void run() {
for (int j = 0; j < 10; j++) {
MyServerByQuene.createOrder(Thread.currentThread().getName() + j);
}
System.out.println(Thread.currentThread().getName() + "結束:" + atomicInteger);
}
}.start();
}
}
}
執行之後,你會發現,無論多少個執行緒去請求,總的正在處理執行緒的數量不會變.
這就是訊息佇列,非同步請求在高併發環境下所起的作用
相關文章
- c# 透過訊息佇列處理高併發請求實列C#佇列
- 徒手擼框架--高併發環境下的請求合併框架
- 高併發架構訊息佇列面試題解析架構佇列面試題
- “簡單”的訊息佇列與kafka佇列Kafka
- 訊息佇列的作用是啥佇列
- 全面理解Handler-1:理解訊息佇列,手寫訊息佇列佇列
- 訊息佇列概念與作用佇列
- 理解訊息佇列(MQ)佇列MQ
- redis訊息佇列簡單應用Redis佇列
- Redis實現簡單訊息佇列Redis佇列
- 訊息佇列簡史佇列
- 訊息佇列中的Oracle佇列Oracle
- EBS提交併發請求的簡單例子單例
- 訊息佇列函式以及其簡單使用佇列函式
- RabbitMQ學習系列二:.net 環境下 C#程式碼使用 RabbitMQ 訊息佇列MQC#佇列
- 訊息佇列批次收發訊息,請避開這 5 個坑!佇列
- 同步、非同步、阻塞、非阻塞的簡單理解非同步
- 程式間通訊--訊息佇列佇列
- node事件迴圈和訊息佇列簡單分析事件佇列
- Redis 應用-非同步訊息佇列與延時佇列Redis非同步佇列
- 用程式碼理解 ObjC 中的傳送訊息和訊息轉發OBJ
- 用程式碼理解ObjC中的傳送訊息和訊息轉發OBJ
- 訊息佇列系列一:訊息佇列應用佇列
- axios躺坑之路:cookie,簡單請求與非簡單請求。iOSCookie
- 訊息佇列佇列
- 二、如何保證訊息佇列的高可用?佇列
- Java併發(10)- 簡單聊聊JDK中的七大阻塞佇列JavaJDK佇列
- 快速理解Kafka分散式訊息佇列框架Kafka分散式佇列框架
- 進階高階IoT架構-教你如何簡單實現一個訊息佇列架構佇列
- 訊息佇列(MQ)佇列MQ
- Kafka訊息佇列Kafka佇列
- RabbitMQ訊息佇列MQ佇列
- kafka 訊息佇列Kafka佇列
- POSIX訊息佇列佇列
- 訊息佇列(一)佇列
- 訊息佇列(二)佇列
- 訊息佇列二佇列
- [Redis]訊息佇列Redis佇列