synchronize同步锁的应用

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

2、同步不能继承,需要在子类的方法中添加synchronize关键字

synchronize同步方法、变量;锁定当前对象

//  异步调用service1()、service2()、service3()方法时,
//  会等待当前调用的方法完成后才调用下一个方法。
public static class Service {
        synchronized private void service1() {
            System.out.println("service1");
            try {
                Thread.sleep(3000);
                System.out.println("service1 end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        synchronized private void service2() {
            System.out.println("service2");
        }

        synchronized private void service3() {
            System.out.println("service3");
        }
    }

synchronize(this)同步代码块,锁定当前对象

synchronize(非this对象x)同步代码块,锁定非this对象x

示例代码:

-----------------重点代码-----------------------
public static class Service {
        private String anything = "";

        private void service1() {
            synchronized (anything) {
                try {
                    System.out.println("service begin");
                    Thread.sleep(3000);
                    System.out.println("service end");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        synchronized private void service2() {
            System.out.println("service2");
        }
    }
    
-----------------重点代码-----------------------
    
     public static class MyThread1 extends Thread {
        private final Service service;

        MyThread1(Service service) {
            this.service = service;
        }

        @Override
        public void run() {
            super.run();
            service.service1();
        }
    }

    public static class MyThread2 extends Thread {
        private final Service service;

        MyThread2(Service service) {
            this.service = service;
        }

        @Override
        public void run() {
            super.run();
            service.service2();
        }
    }


    public static void main(String args[]) {
        try {
            Service service = new Service();
            MyThread1 myThread1 = new MyThread1(service);
            myThread1.start();
            MyThread2 myThread2 = new MyThread2(service);
            myThread2.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

打印结果:

service begin
service2
...
service end

分析:

由于对象监视器不同,所以运行结果就是异步的。

同步代码块放在非同步synchronize方法中进行声明,并不能保证调用方法的线程的执行同步/顺序性,调用方法是无序的,虽然同步块中的执行顺序是同步的,极易出现“脏读”问题

Class锁:对类的所有对象实例起作用。synchronized static private void method()、synchronize(Service.class)

public static class Service {
        public static void method() {
            synchronized (Service.class) {
                System.out.println("Service.class 类锁");
            }
        }
        synchronized public static void method2(){
            System.out.println("类锁");
        }
    }

总结:

public static class Service {
        public void method1() {
            synchronized (Service.class) {
                // Service.class 类锁
            }
        }

        synchronized public static void method2() {
            //  Service.class 类锁
        }

        public void method3() {
            synchronized (this) {
                // 对象锁,Service的实例对象
            }
        }

        synchronized public void method4() {
            // 对象锁,Service的实例对象
        }
    //  一般不使用String作为对象锁,因为常量值相等时是同一个对象
      private final String anything = "";
        public void method5() {
            synchronized (new Object()) {
                // String 对象锁
            }
        }
}

// 只要对象不变,即使对象的属性变化,运行结果还是同步的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值