您的位置:首页 > 编程语言 > Java开发

java知识系列之线程死锁

2013-02-01 14:39 351 查看
线程死锁:

       a线程锁定了1号资源,下一步需要锁定2号资源。

       b线程锁定了2号资源,下一步需要锁定1号资源。

       两个线程无限制的等待下去,于是就出现了死锁。

引用网上的实例:

     

package test;

public class TestDeadLock extends Thread {
static Object o1 = new Object(), o2 = new Object();
int flag = 0;
public void run() {
if(flag == 0){
synchronized (o1) {
System.out.println("a锁定了刀,想要叉");
try {
this.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
System.out.println("a 要叉成功");
}
}
}
if(flag == 1){
synchronized (o2) {
System.out.println("b锁定了叉,想要刀");
try {
this.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1){
System.out.println("b 要刀成功");
}
}
}
}
public static void main(String[] args) {
TestDeadLock tdl1 = new TestDeadLock();
TestDeadLock tdl2 = new TestDeadLock();
tdl1.flag = 0;
tdl2.flag = 1;
tdl1.start();
tdl2.start();
}
}


避免死锁的方法:

        1.让所有的线程按照同样的顺序获得一组锁。这种方法消除了a和b的拥有者分别等待对方的资源的问题。

        2.将多个锁组成一组并放到同一个锁下。前面Java线程死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。

        3.将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。

修改方法1:

package test;

public class TestDeadLock extends Thread {
static Object o1 = new Object(), o2 = new Object();
int flag = 0;
String threadName;
public TestDeadLock(String threadName){
this.threadName = threadName;

}
/**
* 把两个方法合并到一个同步块中
*/
public synchronized void getCanju(){
System.out.println(threadName+"锁定了刀,想要叉");
try {
this.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadName+"要叉成功");

}
public void run() {

getCanju();

}
public static void main(String[] args) {
TestDeadLock tdl1 = new TestDeadLock("线程1");
TestDeadLock tdl2 = new TestDeadLock("线程2");
tdl1.start();
tdl2.start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java