java线程安全之synchronized锁重入及出现异常锁自动释放(五)

科技快讯

      11月16日下午消息,以“Bring AI to Life”为主题的2017百度世界大会今天在北京国贸大酒店和北京嘉里大酒店举行。爱奇艺创始人兼CEO龚宇在大会上发表了主题为“爱奇艺·更懂娱乐”的主题演讲,龚宇表示爱奇艺对于科技的重视与百度的AI创新基因一脉相承。

synchronized锁重入

      关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到了一个对象的锁后,再次请求此对象时是可以再次得到该对象的锁。

案例:
public class SyncDubbo {

    static class Main {
        public int i = 10;
        public synchronized void operationSup(){
            try {
                i--;
                System.out.println("Main print i = " + i);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Sub extends Main {
        public synchronized void operationSub(){
            try {
                while(i > 0) {
                    i--;
                    System.out.println("Sub print i = " + i);
                    Thread.sleep(1000);
                    this.operationSup();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Sub sub = new Sub();
                sub.operationSub();
            }
        });
        t1.start();
    }


}

打印结果:

Sub print i = 9
Main print i = 8
Sub print i = 7
Main print i = 6
Sub print i = 5
Main print i = 4
Sub print i = 3
Main print i = 2
Sub print i = 1
Main print i = 0

出现异常,锁自动释放

案例:
public class SyncException {

    private int i = 0;
    public synchronized void operation(){
        while(true){
            try {
                i++;
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + " , i = " + i);
                if(i == 5){//模拟业务逻辑出现异常,抛出异常,在方法抛出异常的时候会自动解锁
                    throw new RuntimeException();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        final SyncException se = new SyncException();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                se.operation();
            }
        },"t1");
        t1.start();
    }
}

打印结果:

t1 , i = 1
t1 , i = 2
t1 , i = 3
t1 , i = 4
t1 , i = 5
Exception in thread "t1" java.lang.RuntimeException
    at cn.hfbin.base.sync005.SyncException.operation(SyncException.java:18)
    at cn.hfbin.base.sync005.SyncException$1.run(SyncException.java:32)
    at java.lang.Thread.run(Thread.java:745)

说明

      对于web应用程序,异常释放锁的情况,如果不及时处理,很可能对你的应用程序业务逻辑产生严重的错误,比如你现在执行一个队列任务,很多对象都去在等待第一个对象正确执行完毕再去释放锁,但是第一个对象由于异常的出现,导致业务逻辑没有正常执行完毕,就释放了锁,那么可想而知后续的对象执行的都是错误的逻辑。所以这一点一定要引起注意,在编写代码的时候,一定要考虑周全。

源代码:https://github.com/hfbin/Thread_Socket/tree/master/Thread/sync005

    原文作者:java锁
    原文地址: https://blog.csdn.net/qq_33524158/article/details/78549753
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞