死锁DeadLock
当两个对象同时拥有锁时,一个线程已经锁定了对象A,但又想去锁定B,而另一个线程已经锁定了对象B,还想去锁定对象A,这样这两个线程就都会被永远阻塞。多个线程被永远block彼此等待就是死锁。
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s" + " has bowed back to me!%n",this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();//线程1拥有了对象a的锁,在要运行bow方法的bowBack时线程1又想拥有对象g的锁。
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();//线程2拥有了g对象的锁,在要运行bow方法的bowBack时线程2又想拥有对象a的锁。
}
}
因为两个线程同时进行,所以可能会出现线程1还没获取对象g的锁时,线程2已经获取了对象g的锁,那么两个线程就会相互等待对方释放自己需要的锁。
活锁LiveLock
指一个线程可以使用资源,但它让其他线程先使用资源;另一个可以使用资源,但它也让其他线程先使用资源,于是两者一直谦让都无法使用。活锁有一点机率可自行解开而死锁不可解。
//就找到这个一个活锁的例子,自己也没咋搞明白,先放着吧
public class LiveLockThreadTest {
public static void main(String[] args) {
Person zhangsan = new Person("张三");
Person lisi = new Person("李四");
// 张三的朋友是李四
zhangsan.friend = lisi;
// 李四的朋友是张三
lisi.friend = zhangsan;
// 张三先鞠躬
zhangsan.bow();
lisi.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
zhangsan.start();
}
}
public class Person extends Thread {
// 朋友
public Person friend;
// 名字
private String name;
// 鞠躬
private boolean bow;
public Person(String name) {
this.name = name;
}
public void bow() {
this.bow = true;
}
public void up() {
this.bow = false;
}
@Override
public void run() {
while (true) {
// 如果朋友在鞠躬
if (friend.bow) { // 自己也得鞠躬
this.bow();
try {
System.out.println(this.name + " 正在鞠躬 ... ");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 一分钟后鞠躬完成
this.up();
} else {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (friend.bow) {
this.bow();
try {
System.out.println(this.name + " 正在鞠躬 ... ");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.up();
} else {
break;
}
}
}
}
}
Starvation
Starvation描述了当一个线程不能正常访问共享资源以至于不能继续执行下去的情况。例如,线程T1访问资源R,线程T2也请求访问资源R,于是T2等待。T3也请求访问R,当T1释放了R上的锁,系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上的封锁之后,系统又批准了T4的请求……T2可能永远等待,这就是饥饿。