其他活跃性问题
活锁
当多个线程或进程互相谦让资源,同时主动释放让对方先执行,导致所有进程或线程依然在运行,但程序却得不到进展,因为线程总是重复做释放资源的事情浪费着CPU资源,就是活锁
public class LiveLock {
public static void main(String[] args) {
SingleLogBridge singleLogBridge = new SingleLogBridge();
Pedestrian zhangsan = new Pedestrian("张三");
zhangsan.setSingleLogBridge(singleLogBridge);
Pedestrian lisi = new Pedestrian("李四");
lisi.setSingleLogBridge(singleLogBridge);
new Thread(() -> {
lisi.willGo(zhangsan);
}).start();
new Thread(() -> {
zhangsan.willGo(lisi);
}).start();
}
}
class SingleLogBridge {
private Pedestrian pedestrian; //桥上的人
public void setPedestrian(Pedestrian pedestrian) {
this.pedestrian = pedestrian;
}
public Pedestrian getPedestrian() {
return pedestrian;
}
public void goBridge() { //桥上的人过桥
System.out.println(pedestrian.getName() + "过桥了");
pedestrian.setGoBridge(true); //将这个行人状态设置为已过桥
this.pedestrian = null; //过完桥,桥上的人清空
}
}
class Pedestrian {
private String name; //行人名字
private boolean isGoBridge; //是否过已经过桥
private SingleLogBridge singleLogBridge; //桥
public Pedestrian(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setGoBridge(boolean goBridge) {
isGoBridge = goBridge;
}
public boolean isGoBridge() {
return isGoBridge;
}
public void setSingleLogBridge(SingleLogBridge singleLogBridge) {
this.singleLogBridge = singleLogBridge;
}
public void willGo(Pedestrian other) {
while (!this.isGoBridge()) { //没过桥就要过桥
if (singleLogBridge.getPedestrian() == null) { //桥上没人就要上桥
singleLogBridge.setPedestrian(this);
}
if (singleLogBridge.getPedestrian() != this) { //桥上已经有人,就等待
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
continue;
}
if (!other.isGoBridge()) { //对方没过,先让对方过
System.out.println(name + ":" + other.getName() + "你先过");
singleLogBridge.setPedestrian(other);
continue;
}
singleLogBridge.goBridge(); //自己过桥
}
}
}
解决方案:加入随机因素,一定概率的避让资源,将willGo()
方法中的避让代码修改为下面这样(比如以太网指数退避算法)
if (!other.isGoBridge() && new Random().nextBoolean()) { //50%概率的,若对方没过,先让对方过
System.out.println(name + ":" + other.getName() + "你先过");
singleLogBridge.setPedestrian(other);
continue;
}
饥饿
当线程或进程需要某些资源,但是却始终得不到,比如:
- 线程优先级设置的过低,导致该线程无法执行陷入饥饿
- 其他某个线程获得锁陷入无限循环不释放,导致该线程无法执行陷入饥饿
- 某个程序始终占用某文件的写锁,导致该程序无法执行陷入饥饿
解决方案:不应该设置线程优先级,不应该使用完锁不释放
Comments NOTHING