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

来源:互联网 发布:qq影音 知乎 编辑:程序博客网 时间:2024/06/03 15:32


总结了一些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