Java中并发问题

并发问题:

1、synchronized关键字

双重校验锁实现对象单例

public class Singleton {
    private volatile static Singleton uniqueInstance;
    private Singleton() {
    }
    public static Singleton getUniqueInstance() {
       //先判断对象是否已经实例过,没有实例化过才进入加锁代码
        if (uniqueInstance == null) {
            //类对象加锁
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

在代码中uniqueInstance采用volatile关键字修饰,目的是为了禁止JVM的重排序。

这段代码的执行过程为:
1、为uniqueInstance分配内存空间
2、初始化uniqueInstance
3、将uniqueInstance指向分配的内存地址

在JVM中具有指令重排的特性,执行顺序可能变为1->3->2,指令重排在单线程环境下不会出问题,但在多线程环境下会导致一个线程获得还没初始化的实例。
例如T1执行了1和3,此时T2调用了getUniqueInstance()发现uniqueInstance不为空,因此返回uniqueInstance,但此时uniqueInstance还未被初始化。

使用volatile可以禁止JVM的指令重排,保证多线程的环境下也能正常运行。

2、synchronized关键字的底层原理

synchronized同步语句块实现使用的是monitorenter和monitorexit指令,其中
monitorenter指向同步代码块的开始位置,monitorexit指向同步代码块的结束位置。

synchronized修饰的方法并没有monitorenter和monitorexit指令,取而代之的是ACC_SYNCHONIZED标识,该标识指明了该方法是一个同步方法,JVM通过该ACC_SYNCHONIZED访问标志来辨别一个方法是否为同步方法,从而执行相应的同步调用。

3、谈谈synchronized和ReentrantLock的区别?

1、两者都可重入锁。可重入锁的概念是:自己可以再次获取自己的内部锁。
2、synchrnonized依赖于JVM而ReentrantLock依赖于API。ReentrantLock依赖于JDK层面实现的,需要lock()和unlock()方法配合try/finally语句块来完成。
3、ReentrantLock比synchronized增加了一些高级功能。高级功能主要有三点:等待可中断、可实现公平锁、可实现选择性通知

5、volatile关键字

volatile关键字的作用是:保证变量的可见性,在变量钱加volatile关键字就是指示JVM这个变量不稳定,每次使用它都到主存中读取。
还有一个作用是防止指令重排序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值