synchronized锁重入_java培训

发布时间:2020年12月10日作者:atguigu浏览次数:723

synchronized锁重入

可重入锁概念是:自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。

MyThread.java

public class MyThread extends Thread {

    @Override
    public void run() {
        MyThread myThread=new MyThread();
        myThread.service1();
    }

    public synchronized void service1() {
        System.out.println(“service1”);
        service2();
    }

    public synchronized void service2() {
        System.out.println(“service2”);
        service3();
    }

    public synchronized void service3() {
        System.out.println(“service3”);
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

运行结果:

service1
service2
service3

另外可重入锁也支持在父子类继承的环境中 Father.java

public class Father {

    public int i = 10;

    synchronized public void doFatherMethod() {
        try {
            i–;
            System.out.println(“father print i=” + i);
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Sub.java

public class Sub extends Father {

    synchronized public void doSubMethod() {
        try {
            while (i > 0) {
                i–;
                System.out.println(“sub print i=” + i);
                Thread.sleep(100);
                this.doFatherMethod();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

TestFatherAndSub.java

public class TestFatherAndSub extends Thread {

    @Override
    public void run() {
        Sub sub = new Sub();
        sub.doSubMethod();
    }

    public static void main(String[] args) {
        TestFatherAndSub testFatherAndSub = new TestFatherAndSub();
        testFatherAndSub.start();
    }
}

运行结果:

java培训

说明当存在父子类继承关系时,子类是可以通过“可重入锁”调用父类的同步方法。

出现异常时,其持有的锁会自动释放。

注意: * 同步不具有继承性 * 如果父类有一个带synchronized关键字的方法,子类继承并重写了这个方法。 但是同步不能继承,所以还是需要在子类方法中添加synchronized关键字。 * synchronized是串行

Task.java

public class Task {
    private String getData1;
    private String getData2;
   
    public synchronized void doLongTimeTask() {
        try {
            System.out.println(“begin task”);
            Thread.sleep(3000);
            getData1 = “长时间处理任务后从远程返回的值1 threadName=” + Thread.currentThread().getName();
            getData2 = “长时间处理任务后从远程返回的值2 threadName=” + Thread.currentThread().getName();
            System.out.println(getData1);
            System.out.println(getData2);
            System.out.println(“end task”);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Task task = new Task();
        SynThread1 synThread1 = new SynThread1(task);
        synThread1.start();
        SynThread2 synThread2 = new SynThread2(task);
        synThread2.start();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long beginTime = CommonUtils.beginTime1;
        if (CommonUtils.beginTime2 < CommonUtils.beginTime1) {
            beginTime = CommonUtils.beginTime2;
        }
        long endTime = CommonUtils.endTime1;
        if (CommonUtils.endTime2 > CommonUtils.endTime1) {
            endTime = CommonUtils.endTime2;
        }
        System.out.println(“耗时:” + ((endTime – beginTime) / 1000));
    }
}

SynThread1.java

public class SynThread1 extends Thread{

    private Task task;

    public SynThread1(Task task) {
        super();
        this.task = task;
    }

    @Override
    public void run() {
        super.run();
        CommonUtils.beginTime1 = System.currentTimeMillis();
        task.doLongTimeTask();
        CommonUtils.endTime1 = System.currentTimeMillis();
    }
}

SynThread2.java

public class SynThread2 extends Thread{

    private Task task;

    public SynThread2(Task task) {
        super();
        this.task = task;
    }

    @Override
    public void run() {
        super.run();
        CommonUtils.beginTime2 = System.currentTimeMillis();
        task.doLongTimeTask();
        CommonUtils.endTime2 = System.currentTimeMillis();
    }
}

运行结果:

begin task
长时间处理任务后从远程返回的值1 threadName=Thread-0
长时间处理任务后从远程返回的值2 threadName=Thread-0
end task
begin task
长时间处理任务后从远程返回的值1 threadName=Thread-1
长时间处理任务后从远程返回的值2 threadName=Thread-1
end task
耗时:6

synchronized方法耗时很长,可以使用synchronized同步代码块来解决这个问题。

想要了解跟多关于Java培训课程内容欢迎关注尚硅谷Java培训,尚硅谷除了这些技术文章外还有免费的高质量Java培训课程视频供广大学员下载学习


上一篇:
下一篇:
相关课程

java培训 大数据培训 前端培训

关于尚硅谷
教育理念
名师团队
学员心声
资源下载
视频下载
资料下载
工具下载
加入我们
招聘岗位
岗位介绍
招贤纳师
联系我们
全国统一咨询电话:010-56253825
地址:北京市昌平区宏福科技园2号楼3层(北京校区)

深圳市宝安区西部硅谷大厦B座C区一层(深圳校区)

上海市松江区谷阳北路166号大江商厦3层(上海校区)

武汉市东湖高新开发区东湖网谷(武汉校区)

西安市雁塔区和发智能大厦B座3层(西安校区)

成都市成华区北辰星拱青创园(成都校区)