Synchronized关键字

想必大家对这个关键字都很熟悉,毕竟用起来的比较方便和简单的,不需要像用重入锁的时候释放锁,而且此从jdk1.6开始,对Synchronized有很大的优化,性能也得到了一定的提升。

本文将主要围绕Synchronized展开,介绍其用法、原理、以及它是如何保证原子性、可见性和有序性的。

1:Synchronized用法

Synchronized其实是一种内部锁,内部锁是一种排它锁,能够保证原子性、可见性和有序性。Synchronized关键字可以用来修饰方法和代码块。

package sync;

public class SynchronizedDemo {
    //同步方法
    public synchronized void synMethod(){
        System.out.println("同步方法");
    }

    //同步代码块
    public void synChunk(){
        synchronized (SynchronizedDemo.class){
            System.out.println("同步代码块");
        }
    }

}

如果同步的是静态方法相当于当前类对象(Java中的类本身也是一个对象)为引导锁的同步块,如下面的等效的:

  //同步静态方法
    public synchronized void staticMethd(){
        //在此处访问共享数据
    }

    public static void staticMethod(){
        synchronized (SynchronizedDemo.class){
            //在此处访问共享数据
        }
    }

实际上,Java虚拟机及编译器对同步块和同步方法处理方式不同,但是这并不影响我们做出这样的理解。

Synchronized修饰的方法或者代码块,在同一时间,只能被一个线程访问,从而保证线程安全。

2:Synchronize实现原理

可以对上面类用javac进行编译,饭后使用javap命令对.class进行反编译。

对同步方法,JVM采用ACC_SYNCHRONIZED标记符来实现同步。 对于同步代码块。JVM采用monitorentermonitorexit两个指令来实现同步。

同步方法通过ACC_SYNCHRONIZED关键字隐式的对方法进行加锁。当线程要执行的方法被标注上ACC_SYNCHRONIZED时,需要先获得锁才能执行该方法。

同步代码块通过monitorentermonitorexit执行来进行加锁。当线程执行到monitorenter的时候要先获得所锁,才能执行后面的方法。当线程执行到monitorexit的时候则要释放锁。

每个对象自身维护这一个被加锁次数的计数器,当计数器数字为0时表示可以被任意线程获得锁。当计数器不为0时,只有获得锁的线程才能再次获得锁。即可重入锁。

3:Synchronized原子性

原子性是指一个操作是不可中断的,要全部执行完成,要不就都不执行。

在Java中,为了保证原子性,提供了两个高级的字节码指令monitorentermonitorexit。而这两个字节码指令,在Java中对应的关键字就是synchronized

通过monitorentermonitorexit指令,可以保证被synchronized修饰的代码在同一时间只能被一个线程访问,在锁未释放之前,无法被其他线程访问到。因此,在Java中可以使用synchronized来保证方法和代码块内的操作是原子性的。

4:Synchronized可见性

可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

synchronized修饰的代码,在开始执行时会加锁,执行完成后会进行解锁。而为了保证可见性,有一条规则是这样的:对一个变量解锁之前,必须先把此变量同步回主存中。这样解锁后,后续线程就可以访问到被修改后的值。所以,synchronized关键字锁住的对象,其值是具有可见性的。

5:Synchronized有序性

有序性即程序执行的顺序按照代码的先后顺序执行。

虽然synchronized是无法禁止指令重排和处理器优化的,但不管指令怎么重排,在单线程下执行结果都都不会改变。由于synchronized修饰的代码,同一时间只能被同一线程访问。那么也就是单线程执行的。所以,可以保证其有序性。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值