1.死锁的定义
所谓死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。 简单地讲,死锁时过多的同步可能造成相互不是放资源的现象。
2.那么产生死锁的原因是什么
导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性访问权。
3.举个简单的例子
两位女孩,小a占用着口红,持有口红的锁;小c占用着镜子,持有镜子的锁,这个时候,小a想要镜子,小c却想要口红,但小a和小c却相互不释放,两人互相等待对方松开锁。就这样,局面僵持了。。。就死锁了
public class DeadLock{
public static void main(String[] args) {
Markup g1 = new Markup(0, "小a");
Markup g2 = new Markup(1, "小c");
g1.start();
g2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class Markup extends Thread{
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;//选择,0为口红,1为镜子
String girl;
public Markup(int choice, String girl) {
this.choice = choice;
this.girl = girl;
}
public void run() {
markup();
}
private void markup() {
if(choice==0) {
synchronized(lipstick) {
System.out.println(this.girl+"涂口红");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
synchronized(mirror) {
System.out.println(this.girl+"照镜子");
}
}
}else {
synchronized(mirror) {
System.out.println(this.girl+"照镜子");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
synchronized(lipstick) {
System.out.println(this.girl+"涂口红");
}
}
}
}
}
运行结果:
小a涂口红
小c照镜子
4.如何避免死锁
注意不要在同一个代码块中,同时持有多个对象的锁。下面代码对上面例子做简单修改。把第二次的synchronized代码块从第一次的synchronized代码块中移了出来,避免了锁套锁,这样就可以避免死锁了。
public class DeadLock {
public static void main(String[] args) {
Markup g1 = new Markup(0, "小a");
Markup g2 = new Markup(1, "小c");
g1.start();
g2.start();
}
}
class Lipstick{
}
class Mirror{
}
class Markup extends Thread{
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;
String girl;
public Markup(int choice, String girl) {
this.choice = choice;
this.girl = girl;
}
public void run() {
markup();
}
public void markup() {
if(choice==0) {
synchronized(lipstick) {
System.out.println(this.girl+"涂口红");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
synchronized(mirror) {
System.out.println(this.girl+"照镜子");
}
}else {
synchronized(mirror) {
System.out.println(this.girl+"照镜子");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
synchronized(lipstick) {
System.out.println(this.girl+"涂口红");
}
}
}
}
运行结果:
小a涂口红
小c照镜子
小c涂口红
小a照镜子
这样修改后的程序就不会进入死锁状态了,谢谢浏览。。。