java synchronized解析

synchronized在使用上有3种用法
     1.静态方法加关键字
     2.实例方法(即普通方法)加关键字
     3.方法中使用同步代码块
区别:前两种方式最为偷懒,第三种方式比前两种性能要好。

synchronized从锁住的是谁的维度来看一共有两种情况
     1.锁住类
     2.锁住对象实例

(1)静态方法上的锁
     静态方法是属于“类”,不属于某个实例,是所有对象实例所共享的方法,无论定义多少个实例,只要是静态方法上的锁,他自始至终只有1个。也就是说如果在静态方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个类

public class Demo {
    public static synchronized void demo1() {
        while (true) {  //死循环目的是为了让线程一直持有该锁
            System.out.println(Thread.currentThread());
        }
    }
}

(2)实例方法(普通方法)上的锁
     实例方法并不是类所独有的,每个对象实例独立拥有它,它并不被对象实例所共享。这也比较能推出,在实例方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个对象实例

public class Demo {
    public synchronized void demo1() {
        while (true) {  //死循环目的是为了让线程一直持有该锁
            System.out.println(Thread.currentThread());
        }
    }
}

(3)方法中使用同步代码块

     1.synchronized(this){…}

     上面提到,方法中使用同步代码块性能要优于直接使用在方法前加synchronized。但是下面synchronized(this){…}这种写法锁住的仍然是对象实例,它和public synchronized void demo(){}相比可以说仅仅是做了语法上的改变。

public class Demo {
   public void demo1() {
        synchronized (this){
            while (true) {  //死循环目的是为了让线程一直持有该锁
                System.out.println(Thread.currentThread());
            }
        }
    }

	public void demo2() {
        synchronized (this){
            while (true) {  //死循环目的是为了让线程一直持有该锁
                System.out.println(Thread.currentThread());
            }
        }
    }

}

     也许后者在JVM中可能会做一些特殊的优化,但从代码分析上来讲,两者并没有做到很大的优化,线程1执行demo1,线程2执行demo2,由于两个方法均是抢占对象实例的锁,只要有一个线程获取到锁,另外一个线程只能阻塞等待,即使两个方法不相关

     2.private Object obj = new Object(); synchronized(obj){…}

public class Demo {
        private Object lock1 = new Object();
        private Object lock2 = new Object();
        public void demo1() {
            synchronized (lock1){
                while (true) {  //死循环目的是为了让线程一直持有该锁
                    System.out.println(Thread.currentThread());
                }
            }
        }

        public void demo2() {
            synchronized (lock2){
                while (true) {  //死循环目的是为了让线程一直持有该锁
                    System.out.println(Thread.currentThread());
                }
            }
        }

    }

     经过上面的分析,看到这里,你可能会开始懂了,可以看到demo1方法中的同步代码块锁住的是lock1对象实例,demo2方法中的同步代码块锁住的是lock2对象实例。如果线程1执行demo1,线程2执行demo2,由于两个方法抢占的是不同的对象实例锁,也就是说两个线程均能获取到锁执行各自的方法(当然前提是两个方法互不相关,才不会出现逻辑错误)。

     3.synchronized(Demo.class){…}

     这种形式等同于抢占获取类锁,这种方式,同样和方式1一样,收效甚微。方式2中的方式才是最佳的代码优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值