惊群效应是什么?如何避免惊群效应?
Java juc 面试 About 1,680 words线程惊群
惊群效应(thundering herd
)是指多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只能有一个进程(线程)获得这个时间的“控制权”,对该事件进行处理,而其他进程(线程)获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应。
性能影响
Linux
内核对用户进程(线程)频繁地做无效的调度、上下文切换等使系统性能大打折扣。上下文切换(context switch
)过高会导致CPU
像个搬运工,频繁地在寄存器和运行队列之间奔波,更多的时间花在了进程(线程)切换,而不是在真正工作的进程(线程)上面。
代码示例
在一段无缓存则请求数据库的代码中,当高并发时只有一个线程能获取到锁,其他线程都休眠1
秒,1
秒后可能有成千上百个线程从休眠中被唤醒来争夺锁,但也只有一个线程能获取到锁,其他线程又继续休眠等待。
public String getData2(String keywords) throws InterruptedException {
String data = getDataFromCache(keywords);
if (data == null) {
while (!lock.tryLock()) {
TimeUnit.SECONDS.sleep(1);
}
try {
data = getDataFromCache(keywords);
if (data == null) {
data = getDataFromDB(keywords);
saveToCache(keywords, data);
}
} finally {
lock.unlock();
}
}
return data;
}
退避策略
增加随机策略,每次休眠的时间为一个随机数,避免多个线程同一时间被唤醒。
public String getData3(String keywords) throws InterruptedException {
String data = getDataFromCache(keywords);
if (data == null) {
while (!lock.tryLock()) {
// 使用随机数,免出现惊群效应,防止相同时间执行大量操作
long randomSleepTs = ThreadLocalRandom.current().nextLong(1000);
TimeUnit.MILLISECONDS.sleep(randomSleepTs);
}
try {
data = getDataFromCache(keywords);
if (data == null) {
data = getDataFromDB(keywords);
saveToCache(keywords, data);
}
} finally {
lock.unlock();
}
}
return data;
}
缓存惊群
缓存惊群换个名词就是缓存击穿、缓存踩踏。当缓存过期时,大量并发请求直接到数据库请求。
参考
Views: 7,458 · Posted: 2021-03-24
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...