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");
                }
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值