-
as-if-serial查看全部
-
重排序查看全部
-
线程执行互斥代码的过程查看全部
-
JMM对synchronized实现可见性的要求查看全部
-
线程与各自的工作内存已经共享变量之间的规则查看全部
-
JMM的主内存和线程各自的工作内存查看全部
-
内存可见性和共享变量的定义查看全部
-
内存模型查看全部
-
volatile适用场景查看全部
-
总结 1,Java中没有提供检测与避免死锁的专门机制,但应用程序员可以采用某些策略防止死锁的发生 2. JAVA中对共享数据操作的并发控制是采用加锁技术 3. 共享数据的访问权限都必须定义为private 4.另外两点补充 (1)如图,程序执行的大多数情况都能保证可见性,因为CPU执行速度很快,刷新缓存也很快。只有在短时间内高并发的情况才可能出现可见性的问题 (2)对64位(long、double)变量的读写可能不是原子操作 因为Java内存模型允许JVM将没有被volati修饰的64位数据类型的读写操作分两次32位的读写操作来执行 这样就导致了读写“半个变量”的情况 解决方法:volatile查看全部
-
synchronized和volatile的比较 如图,需要说明: volatile虽然不能保证执行的原子性,但是它执行起来比较轻量,高效,所以在可以保证程序执行正确的情况下,尽量还是使用volatile,比如前一节所讲的情况查看全部
-
volatile适用场合 如图,对于第二点需要说明: 比如程序中有多个volatile变量,那么每个volatile变量之间就要相互独立,不存在相互依赖的关系,比如"下一个变量<上一个变量"这样的判断查看全部
-
volatile不能保证执行的原子性 1.程序主体如下 public void increase(){ this.number++ ; } public static void main(String[] args) { // TODO Auto-generated method stub final VolatileDemo volatileDemo = new VolatileDemo(); for (int i = 0; i<500; i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub volatileDemo.increase(); } }).start(); } //如果还有子线程在执行,主线程让出CPU资源,直到所有的子线程执行完,主线程才继续执行,打印number的值 while(Thread.activeCount() > 1){ Thread.yield(); } System.out.println("number = " + volatileDemo.getNumber()); } 2.这个执行结果number不一定为500,原因如图 3.解决方法 (1)使用synchronized关键字 public void increase(){ synchronized(this){ this.number++ ; } } (2)使用Reentrantlock private Lock = new ReentrantLock(); public void increase(){ lock.lock(); try{ this.number++ ; }finally{ lock.unlock(); } } (3)使用AtomicInterger 后面两种是高版本jdk才有的查看全部
-
volatile的适用范围,不包括++操作 a=a*5这种依赖当前值的形式,因为该关键字不能保证原子性,而这些操作是可以分成3部分的查看全部
-
和同步锁原理一样,多了两条指令而已,而且能够禁止重排序查看全部
举报
0/150
提交
取消