线程安全,关键字synchronized的其他基本特性(可重入锁)


总结了一些synchronized的一些特性,不足之处望指出。

synchronized的基本特性:

1,synchronized的锁重入
解释:可重入,从字面上可以看出,这个锁,可以两次获取。即当一个线程获取对象A的锁,然后其代码执行过程中(未释放对象A的锁)可以再次请求对象A的锁,并且可以再次获得对象A的锁,而不是出现死锁问题。而关键字synchronized有这一特性,属于可重入锁。
代码如下:
public class SynchronizedDemo {

    public synchronized void method1(){
        System.out.println("method1");
        mothed2();
    }
    public synchronized  void method2(){
        System.out.println("method2");
    }

    public static void main(String...args){
        final SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedDemo.method1();
            }
        }).start();
    }
}

输出结果:
method1;
method2;
由输出结果可以看出,创建的线程两次获取了synchronizedDemo对象的锁,验证了synchronized是可重入锁。
引入可重入锁的意义?
自己可以获取自己的内部锁。这样做避免了第二次调用同一对象锁时出现死锁。
实际开发中,订单修改,订单验证(库存验证等)都应该加上synchronized锁;当你做订单修改时,先要做订单验证,(两次获取订单对象锁)这样就用到了可重入锁。等等。

可重入锁的其他性质——父子继承
代码如下:
public class SynchronizedDome1 {
    public synchronized void method1()  {
            System.out.println("method1");
    }
    static class SynchronizedDemo2 extends SynchronizedDome1{
        public synchronized void method2() {
                System.out.println("method2");
                method1();
        }
    }
    public static void main(String...args){
        final SynchronizedDemo2 synchronizedDemo2 = new SynchronizedDemo2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo2.method2();
            }
        }).start();
    }

}
输出结果:
method2;
method1;
说明获取了子类对象锁可以再次重入父类对象锁。
2,出现异常后,锁自动释放。
代码如下:
public class SynchronizedDome2 {
    public int i = 10;
    public String str;
    public synchronized void method1()  {
            for(;i>0;i--){
               System.out.println("i:"+i);
              if(i==3){
                 str.toCharArray();
              }
            }
    }
    public static void main(String...args){
        final SynchronizedDemo2 synchronizedDemo2 = new SynchronizedDemo2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo2.method1();
            }
        }).start();
    }
}
输出结果:
i:9
i:8
i:7
i:6
i:5
i:4
i:3
java.lang.NullPointerException
at thread.SynchronizedDome2.method1(SynchronizedDome2.java:10)
at thread.SynchronizedDome2$1.run(SynchronizedDome2.java:19)
at java.lang.Thread.run(Thread.java:745)
表明当出现异常后,程序不继续运行,将对象锁释放。
3,将对象作为监听器。
public class SynchronizedDome3 {
    public String str = "lock";
    public void method1()  {
       synchronized (str){   
       System.out.println("当前线程名:"+Thread.currentThread().getName());
            }
    }
    public static void main(String...args){
        final SynchronizedDemo3 synchronizedDemo3 = new SynchronizedDemo3();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo3.method1();
            }
        },"name1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo3.method1();
            }
        },"name2").start();
    }
}
当前线程名:name2
当前线程名:name1
或者
当前线程名:name1
当前线程名:name2
说明: 选取任意对象作为锁
4,单例模式---双重校验锁(懒汉式)
public class SingleCase {
 private static SingleCase instance2;

public static SingleCase getInstance2(){
    if(instance2 == null){
        synchronized(SingleCase.lass){
            if(instance2 == null){
                instance2 = new SingleCase();
            }
        }
    }
    return instance2;
}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值