11.并发包-下
博客概述
在这篇博客里面主要进行并发包的一些工具类的讲解,主要是作用的讲解以及代码演示下篇。
Concurrent.util常用类
Semaphore
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层面实现很简单,不考虑业务就太简单了。
应用场景漫谈
java做限流手段比较单一,redis做限流比较多(设置过期时间)。
比如:限制每个IP单位时间之内的访问次数。
把IP存在redis中,然后有计数器,超过多少次就被拒绝访问。
提示:您访问过于频繁,请稍后再试。
每过一分钟就会刷新这个计数为0.没访问一次就++
如果访问次数过多,判断出非人为操作,就给你封停。
大方向的面对高并发的技术就是nginx配合keepalived技术这种(haproxy+lvs)。
代码级别能做的很少。
最主要的还是业务细粒度。