Java多线程8 并发的另一个弊端——死锁
程序员文章站
2024-01-22 22:31:16
...
多线程的弊端:1.降低了效率——使用双重判断
2.1 在线程任务中出现了多个同步(同步的区别在于锁)时,如果同步中嵌套了其他同步这是容易引发一种现象-----------死锁。
synchronized(obj1){//1
synchronized(obj2){//2
}
}
synchronized(obj2){//3
synchronized(obj1){//4
}
}
此时就会出现死锁:假设此时有两条路径(逐行分析)
(1) 线程0 获取obj1 此时CPU切换,(3) 线程1 获取obj2, (4) 在第四行代码时线程1是无法获取obj1 的,因为 obj1 在线程0中。在这样的情况下就会出现死锁。CPU还是在照常的切换,但是,程序是不会继续向下执行的同时也是看不出来任何问题的。
在这种情况下有一种叫和谐:也就是先执行完1.2 在执行3.4。这种呢,完全取决于CPU的切换。但部分情况下都会出现死锁。
这个是死锁的一种情况,死锁还有几种情况。只要线程停住不执行了,就叫做死锁。
在写程序的时候能避免,就避免死锁,不然就会死的很难看!!!!!
但是要知道明白死锁,联系写一段代码:
package Thread;
/*
测试死锁
*/
class Locking implements Runnable{
private boolean flag;
Locking(boolean flag){
this.flag = flag;
}
public void run(){
if(flag){
synchronized (MyLock.obj1){
System.out.println(Thread.currentThread().getName()+" if.....obj1");
synchronized (MyLock.obj2){
System.out.println(Thread.currentThread().getName()+" if.....obj2");
}
}
}
else{
synchronized (MyLock.obj2){
System.out.println(Thread.currentThread().getName()+" else.....obj1");
synchronized (MyLock.obj1){
System.out.println(Thread.currentThread().getName()+" else.....obj2");
}
}
}
}
}
class MyLock{
public static Object obj1 = new Object();
public static Object obj2 = new Object();
}
public class DeadLock {
public static void main(String[] args){
Locking l1 =new Locking(true);
Locking l2 = new Locking(false);
Thread T1 = new Thread(l1);
Thread T2 = new Thread(l2);
T1.start();
T2.start();
}
}
从运行结果来看是发生了死锁(当然,如果你运行N遍,有可能会出现和谐状况//可见死锁的可怕)
注意:关于创建了两个线程任务任然可以的原因:(这段代码是可以这样的)
1.没有共享数据
2.也是最重要的一点,两个锁是固定的,在这段程序中,从头到尾所都有且只有两个 obj1 obj2.
如果代码换成这样(修改锁)
Object obj = new Object();
public void run(){
if(flag){
synchronized (obj){
System.out.println(Thread.currentThread().getName()+" if.....obj1");
synchronized (this){
System.out.println(Thread.currentThread().getName()+" if.....obj2");
}
}
}
else{
synchronized (this){
System.out.println(Thread.currentThread().getName()+" else.....obj1");
synchronized (obj){
System.out.println(Thread.currentThread().getName()+" else.....obj2");
}
}
}
}
}
是锁不住的