static修饰成员变量出现死锁-Java
static变量只在类加载时创建
被static修饰的变量只会在类加载时创建一次,之后new实例都不会再创建
死锁是对象互相想锁住对方,但是对方又在执行中,无法被锁住,造成:我等他结束,他等我结束,但是任何一方却无法单独结束的死循环情况。
Object o1 = new Object();
Object o2 = new Object();
当new两个类对象时,没有被static修饰,hashcode是这样的:
397829811: 426875445 //第一个实例对象的O1,O2
1272570722: 1159599209 //第二个实例对象的O1,O2
当被static修饰时:
static Object o1 = new Object();
static Object o2 = new Object();
1735802339: 1773260669
1735802339: 1773260669
synchronized锁的是同一个变量
当t1被执行时o1被锁住,执行代码块,休眠0.5s时,t2拿到时间片,被执行,锁住o2,也被休眠0.5s,这时候t1睡眠结束,执行接下来的代码块,要锁住o2,但由于此时o2没有被释放,被t2锁住,所以无法执行,而t2执行时也是同样的道理,无法锁住被t1锁住的o1,所以形成死锁。
if(flag == 2){
synchronized (o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("O1");
synchronized (o2) {
System.out.println("o2");
}
}
}
如果t1执行时,没有Thread.sleep(500)
,那么执行速度太快t1有机会锁住o2,即t2还没执行到锁住o2的阶段,那么就不会出现死锁。
if(flag == 0){
synchronized (o2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("02KAIS");
synchronized (o1){
System.out.println("OK");
}
}
}
注意,所以锁住的不是由static修饰的变量,那么就是不同实例所属的对象,不是同一对象,不会出现等待对象释放的情况,不会出现死锁,如果没有Thread.sleep(500)
,可能其中一个线程执行完了才轮到下一个,所以可能会有不出现死锁的情况。
package com.ma;
public class DeadLock implements Runnable{
int flag = 2;
static Object o1 = new Object();
static Object o2 = new Object();
public static void main(String[] args) {
DeadLock r1 = new DeadLock();
DeadLock r2 = new DeadLock();
r1.flag = 2;
r2.flag = 0;
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
@Override
public void run() {
System.out.println("object: " + flag );
System.out.println(o1.hashCode() + ": " + o2.hashCode());
if(flag == 2){
synchronized (o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("O1");
synchronized (o2) {
System.out.println("o2");
}
}
}
if(flag == 0){
synchronized (o2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("02KAIS");
synchronized (o1){
System.out.println("OK");
}
}
}
}
}