synchronized关键字

一、synchronized的特性

1.互斥

        当某个线程已经执行到某个对象的synchronized中时,如果其他线程也执行到同一个对象的synchronized,就会发生阻塞。

        进入被synchronized修饰的方法使,相当于对当前对象加锁;方法执行完毕时,相当于对当前对象解锁。

2.可重入

        synchronized 同步块对同一条线程来说是可重入的,不会出现死锁问题。

二、synchronized的使用

1.修饰代码块

//锁对象
synchronized(this){
...
}

//锁类对象
synchronized(className.class){
...
}

         锁对象时,同一个类的不同对象有不同的锁,对象之间不会出现锁竞争;锁类对象时,同一个类的不同对象用同一把锁,对象之间也会出现锁竞争。

2.修饰方法

public synchronized void methondName() {}

相当于

public void methondName() {
    synchronized(this) {
    ...
    }
}

3.修饰静态方法

public static synchronized void methondName() {}

相当于

public void methondName() {
    synchronized(methondName.class) {
    ...
    }
}

三、synchronized的锁机制

1.锁升级

        JVM将synchronized锁分为:无锁、偏向锁、轻量级锁、重量级锁,根据实际情况,依次升级(不会降级)。

偏向锁:

        偏向锁是一种准备加锁但还没有加锁的状态,只是给对象头做了一个标记。

        第一个尝试加锁的线程,优先进入偏向锁状态。如果后续没有线程来竞争该锁,就节省了一次加锁解锁的开销;但是如果后续有线程来竞争该锁,那就会取消偏向锁状态,进入轻量级锁状态。类似于小时候在家里偷偷看电视,虽然我们在看电视,但是一旦有风吹草动,我们就可以以迅雷不及掩耳之势关掉电视,防止被父母发现。 

轻量级锁: 

        自适应的自旋锁,通过CAS实现。

        自旋锁会让CPU一直空转,处于忙等状态,比较浪费CPU资源,但好处是响应快。

        自旋不会一直持续下去,达到一定的时间/次数就不再自旋了,因此称为“自适应”。

重量级锁: 

        自旋不能快速获取到锁状态,就会膨胀为重量级锁。实际上就是内核提供的 mutex。

2.锁消除

        如果编译器和JVM确信某处代码可以不加锁,就直接消除。

3.锁粗化

        如果一段逻辑中多次出现加锁解锁操作,编译器和JVM会自动进行锁粗化。

锁的粒度:粗和细

        一段代码,如果每条语句都加同一把锁,就是细;如果将整段代码加锁,就是粗。频繁的加锁解锁操作会消耗大量的资源。

例如

while(...){
    synchronized{
        n++;
    }
}

 会被自动粗化为

synchronized{
    while(...){
        n++;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值