volatile实现内存可见性
深入来讲:
通过加入内存屏障和禁止重排序优化来实现的
对volatile变量执行写操作时,会在写操作后加入一条store的屏障指令
对volatile变量执行读操作时,会在读操作前加入一条load屏障指令
线程写volatile变量的过程
1.改变线程工作内存中volatile变量副本的值
2.将改变工作内存副本中的值刷新到主内存中区
线程读volatile变量的过程
1.从主内存中读取volatile变量的最新值到线程的工作内存中
2.从工作内存中读取volatile变量的副本
volatile不能保证变量复合操作的原子性
private int number=0;
number++;
1.读取number的值
2.将number的值加1
3.写入最新的number
注意:
volatile不能实现原子性,不是线程安全的
package com.example.demo;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by 小波哥 2018/9/28 9:51
实现自增变量线程安全性的三种办法
第一种:使用jdk1.5 java.util.concurrent 自带的lock锁
第二种:使用同步锁 synchronizend 实现
第三种:使用jdk1.5后提供的Atomic下的AtomicInteger 或者使用LongAddr
*/
public class ThreadSafeAddCount {
public static void main(String[] args) {
CountDownLatch latch=new CountDownLatch(1000);
ThreadSafeCount count=new ThreadSafeCount(latch);
for (int i = 0; i <1000 ; i++) {
new Thread(count,"线程"+i).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count.getCount());
}
}
class ThreadSafeCount implements Runnable{
private CountDownLatch latch;
public ThreadSafeCount(CountDownLatch latch){
this.latch=latch;
}
Lock lock=new ReentrantLock();
/*
使用Atomicinter实现
private AtomicInteger count=new AtomicInteger();
public int getCount() {
return count.getAndIncrement();
}
*/
/**
使用synchronized 实现
* public synchronized int getCount() {
* return count++;
* }
*/
private int count;
public int getCount() {
return count++;
}
@Override
public void run() {
try{
Thread.sleep(100);
lock.lock();
getCount();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
latch.countDown();
}
}
}
默认使用lock实现