文章目錄
- 部落格概述
- Concurrent.util常用類
- Semaphore
- 高并發解決方案
- 應用場景漫談
部落格概述
在這篇部落格裡面主要進行并發包的一些工具類的講解,主要是作用的講解以及代碼示範下篇。
Concurrent.util常用類
Semaphore
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CMwAjM4QWZxMTOzczY1I2NzYzX5MTOwkTMxIzLcFTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class UseSemaphore {
public static void main(String[] args) {
// 線程池
ExecutorService exec = Executors.newCachedThreadPool();
// 隻能5個線程同時通路
final Semaphore semp = new Semaphore(5);
// 模拟20個用戶端通路
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 擷取許可
semp.acquire();
System.out.println("Accessing: " + NO);
//模拟實際業務邏輯
Thread.sleep((long) (Math.random() * 10000));
// 通路完後,釋放
semp.release();
} catch (InterruptedException e) {
}
}
};
exec.execute(run);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println(semp.getQueueLength());
// 退出線程池
exec.shutdown();
}
}
執行效果:每次進入5個。考慮到鎖競争,為啥不會出現01234的原因.
高并發解決方案
- 網絡端。dns,路由這些比較高端的。
- 服務端,比如加幾個nginx,實作分流的政策。nginx,hyproxxy或者lvs
-
解決高并發,最重要的不是技術。
而是業務的子產品化,細粒度的分開。
業務:實作業務的細粒度分開。
例子:JD,天貓有購物車系統,支付系統。XXX系統這些,子產品細粒度的區分。
整體上進行業務劃分。遇到單一子產品需要強化,可以單獨強化某一個子產品。對某個子產品再負載均衡。
最重要的就是對業務的子產品化。購物車系統有獨立域名,跟其他不相關。
-
并發還是大,java層面去解決。java層面去做限制(限流)。
技術比較牛逼可以自己定制nginx,自己做限流。
使用信号量去做限流。技術上實作很簡單。簡單來說就是一個執行權限的分發與回收器,拿到執行權限的線程才可以運作。就像一把鎖,但是可以有多個線程進入,此處是5個。第六個線程進來就會阻塞,阻塞在請求擷取權限的api。java層面實作很簡單,不考慮業務就太簡單了。