实现同步的几种手段
关于内存可见性
在jvm的内存模型中,每个线程将自己管理的变量从主内存从读取到自己的副本中,此后对这些变量的修改都是在副本中进行。至于什么时候会将副本中更新的值刷回到主内存中,这是不一定的。因此,如果没有同步,一个线程对某一共享变量进行修改后,另一线程并不知道该值变化了。
原子性问题
cpu会对指令进行重排序,以达到更加高效的运行速度,单线程的情况下这不会有问题,但是多线程情况下,可能会出现脏读的情况。
synchronized关键字
与object对象的wait()、notify()、notifyAll()方法配合使用,synchronized关键字用于获取对象的监视器锁。
wait() 方法会阻塞当前线程,同时释放该对象的监视器锁;
notify() 方法随机唤醒一个被当前对象阻塞的线程;
notifyAll() 方法唤醒所有被当前对象阻塞的线程,然后线程间开始竞争,具体哪一个线程开始执行是不确定的。
synchronized修饰类 、静态方法 :对该类产生的所有对象加锁。
synchronized修饰成员方法、 代码块 : 对调用该方法的对象加锁。
synchronized 内存语义:
- 进入synchronized代码块: