造成线程无法运行的情况,但是没有阻塞,在做一件循环的事情,没有任何进展
例如: 哲学家就餐的例子,同时拿起左边的筷子,所有哲学家等待五分钟,同时放下手中的筷子,再等五分钟,再同时拿起
这样就会导致活锁,因为这些动作一直在循环,并没有停下来,解决这个问题
让所有人等待的时间为随机
缺乏共享资源
虽然线程并没有阻塞,也始终在运行(所以叫做"活"锁,线程是"活"的),但是程序却得不到进展,因为线程始终重复做同样的事情
耗费资源
活锁的重要逻辑代码:
while(isHungry){
//当前拥有者不是自己 等待
if(spoon.owner != this){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
continue;
}
//自己如果不是饥饿的 那就让出
if(diner.isHungry){
System.out.println(this.name + ":" + "哈哈哈," + diner.name + "你先吃吧");
spoon.setOwner(diner);
continue;
}
//自己先吃
spoon.use();
isHungry = false;
System.out.println(this.name + ":我吃完了");
spoon.setOwner(diner);
}
解决活锁:
- 导致原因 重试机制不变,消息队列始终重试,吃饭始终谦让
- 以太网的指数退避算法
- 加入随机因素
//自己如果不是饥饿的 那就让出 if(diner.isHungry){
//加入随机性 来解决活锁 ,目前是百分之10的概率 不谦让
Random random = new Random();
if(diner.isHungry && random.nextInt(10) < 9){
System.out.println(this.name + ":" + "哈哈哈," + diner.name + "你先吃吧");
spoon.setOwner(diner);
continue;
}