java多线程(复习-2)对象及变量的并发访问

一,几个重要的结论。

1,方法内部的私有变量是线程安全的,因为私有,不存在共享问题,也就不会竞争。

2,实例变量是非线程安全的,当多个线程队一个实例变量并发访问,就会发生脏读,解决方法就是加锁。

3,使用synchronized 同步的方法,一定是排队执行的,一个执行完毕之后再执行下一个。只有“共享资源”在读写的时候,才需要同步化,否则没有必要。

4,synchronized方法的  取得的锁都是对象锁,而不是一段代码,这种加锁方式 ,是由jvm创建的

 5,使用synchronized 同步代码块的方式 取得的锁是当前调用对象的锁

6,同一时间只有一个线程可以执行同步方法或同步代码块内的的代码

7,静态方法在使用同步时,所加的锁 是在Class类上加锁。

8,在一个类中有很多同步方法, 在使用同步代码块时使用 非this对象 时,可以提高效率

二,synchronized(String)同步代码块,与String一起连用使会多个线程取得锁使同一把锁。

这时由于jvm中的String常量池 具有缓存 功能。会使多个值相同的对象 指向堆中的同一个引用,那么多个线程就会获得同一把锁,从而导致其他线程不能被执行,(百度词条:Java字符转常量池)

所以synchronized(String)一般不会使用,使用new Object();

三,volatile 与 Synochronized 的比较;

1,关键字volatile是线程同步的轻量级实现,性能会快于后者。但是这两个东西有明显的区别 两者不能等同

         1)volatile 特性1,使用Volatile 定义的变量,可以保证此变量的对所有线程的可见性(例如:一个线程修改了 一个volatile变量的值,那么其他线程去读这个值时,这个值在主内存中总是最新的,但是基于volatile变量的运算在并发下并不是安全的,因为有的运算不是原子性的,);

          特性2,禁止指令重拍,普通变量在进行赋值操作的顺序并不是按照我们代码所写的顺序,jvm 会自动优化。

            2)volatile的运用场景:运算结果不依赖变量的当前值,或者只有一个单一线程修改变量的值,

                       变量不需要与其他的状态变量共同参与不变约束,(大概理解为该变量不参与运算, 具体分析可以看看jvm)

2,多线城访问volatile变量不会发生阻塞,后者会阻塞

3,volatile能保证数据的可见性,但不保证数据的原子性。

猜你喜欢

转载自blog.csdn.net/qq_36099832/article/details/89739301
今日推荐