前言:
此刻朋友们对“nginxlua防刷”大致比较关注,各位老铁们都需要知道一些“nginxlua防刷”的相关内容。那么小编同时在网络上网罗了一些有关“nginxlua防刷””的相关资讯,希望看官们能喜欢,朋友们一起来了解一下吧!在写并发代码来提升性能时,会遵循某些最佳写法,而不是只用基础的wait和notify来控制复杂的流程。Java.util.concurrent 包是专为 Java并发编程而设计的包,它下有很多编写好的工具,使用这些更高等的同步工具来编写代码,让我们的程序可以不费力气就得到优化。这些工具还在由一些优秀的工程师不断优化和完善,我们不必重复造轮子:
脑图地址,感谢深入浅出 Java Concurrency ,此脑图在这篇基础上修改而来。其中我们先看工具类部分:
1.ReentrantLock
2.Condition
3.Semaphore
4.ReentrantReadWriteLock
5.CountDownLatch
6.CyclicBarrrer
1.ReentrantLock
1.1可重入
单线程可以重复进入,但必须重复退出。
一个线程拿到几个许可,就得释放几次,不然就造成线程等待,可在命令行查看等待的线程:jps -->jstack [ option ] pid
1.2可中断
长期线程在锁上等待问题,可以通过中断来解决:
可在命令行查看死锁:jps -->jstack [ option ] pid
1.3可限时
可限时也是一个避免永久等待构成死锁的解决方法:
p
1.4公平锁
先来的线程先得到锁。如果先来的线程一直拿不到锁,则会产生饥饿现象,公平锁虽然不会产生饥饿现象,因为产生排队问题,会导致程序效率差。通过阅读ReentrantLock的源码发现:默认是非公平的,如果传入true,则是公平锁:
2.Condition
Condition与ReentrantLock的关系就类似于synchronized与Object.wait()/notify()。但是它与ReentrantLock结合使用,有await和signal与之对应.
利用Condition实现顺序执行:
3.Semaphore
翻译为信号量,允许多个线程进入临界区。说白了就是一个广义上的锁,相当于共享锁。比如信号量中我可以给它指定10个许可,每一个许可可以分配给若干个线程(当然一个线程也可以拿多个许可),拿到许可线程可以执行,如果许可分发完了,后面的线程就和锁一样去做等待。换句话说,当信号量等于1的时候,就相当于一把锁。
比如早期做限流时,我们系统是8核cpu,设置同时请求任务为8个,超过8个,可以用信号量让线程等待来加以控制:
一般限流java用的不多,实际中一种思路是用redis,存用户的session到redis中,统计一分钟之内访问url的次数count,如果count大于额定次数,则是恶意攻击。redis里有个expried,每过60秒,把index清零,然后重新统计。现在互联网公司成熟的限流方案是使用:nginx + lua + redis 防刷和限流。
4.ReentrantReadWriteLock
ReentrantReadWriteLock,首先要做的是与ReentrantLock划清界限, 它和后者都是单独的实现,彼此之间没有继承或实现的关系。读写锁可以很好的提高程序效率,如果读也加锁的话,每次只有一个线程能访问,不符合高并发程序设计。ReentrantLock和synchronized都属于阻塞的并行,会把线程挂起,而ReadWriteLock属于无等待的并发。
访问情况:读读共享,读写互斥,写写互斥
5.CountDownLatch
实际开发中经常用于监听某些初始化操作,等待初始化完成后,通知主线程继续工作,它相当于一个栅栏
6.CyclicBarrrer
倒数计时器。假设有一个场景:每个线程代表一个跑步运动员,当运动员都准备好后,才能一起出发,只要有一个人没有准备好,大家都等待:
最后,我们解决高并发可以从以下几个方面入手:1.Nginx网络带宽硬件方面等。2.业务细粒度化。3.限流。4.集群。5.异步。6.缓存。其中最主要的还是业务细粒度化。
标签: #nginxlua防刷