杂笔

1、原子性:是指单一不可分割的操作,在多线程的环境中,非原子性操作可能会受其他线程的影响,synchronized关键字可以很好的解决这个问题。

2、synchronized:保持原子性操作,保证内存的可见性。CPU在执行代码的时候,为了减少变量访问的时间消耗,可能将代码中访问的变量存入该CPU的缓存区,所以下一次读取的时候,相应的值是来自缓存中而非主内存,同样的代码中对那些缓存过的变量的值的修改也可能仅被写入CPU的缓存区,这就引起一个问题,由于每个CPU都有自己的缓存区,本身CPU的改动是对其他CPU不可见的,所以也不无法知道某个线程对一个变量的修改,这就是内存可见性。而synchronized关键字可以很好的解决这一个问题,能保证这个变量的修改被其他CPU所知晓,不会读到一些过期的值。volatile关键字也能够保证内存可见性,被称为轻量级的锁,但是它不能保证操作的原子性,这是和synchronized的差别。

3、volatile:实现内存可见性的机制:当一个线程对一个变量进行修改的时候,直接把修改的内容存入主内存而不是仅仅该CPU的缓存中,其他CPU存储的该变量的值也会失效,这就保证其他线程访问volatile修饰的变量的时候读到的永远都是最新的值。

Volatile、synchronized两者的区别联系

1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的。
3.volatile仅能实现变量的修改可见性,不能保证原子性(线程A修改了变量还没结束时,另外的线程B可以看到已修改的值,而且可以修改这个变量,而不用等待A释放锁,因为Volatile 变量没上锁);而synchronized则可以保证变量的修改可见性和原子性。
4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞和上下文切换。
5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。

6.在使用volatile关键字时要慎重,并不是只要简单类型变量使用volatile修饰,对这个变量的所有操作都是原子操作。当变量的值由自身决定时,如n=n+1、n++ 等,volatile关键字将失效。只有当变量的值和自身无关时对该变量的操作才是原子级别的,如n = m + 1,这个就是原级别的。所以在使用volatile关键时一定要谨慎,如果自己没有把握,可以使用synchronized来代替volatile。

这也就是有道面试题:String s = new String(“xyz”);产生几个对象?一个或两个,如果常量池中原来没有”xyz”,就是两个

猜你喜欢

转载自www.cnblogs.com/luliangliang/p/9067022.html