java并发编程:volatile 关键字解析

时间:2022-06-25 17:56:32

这篇文章将并发编程的概念讲得很清楚: 点击打开链接

Java并发编程:volatile关键字解析

从并发编程的三个概念讲起:原子性、可见性、有序性。

原子性(整体,要么执行、要么不执行)

可见性(当前的修改使后续得缓存失效)

有序性(顺序执行)


voliatile  可以保证可见性、有序性,但原子性不一定能够保证。

public class Test {
public int inc = 0;
Lock lock = new ReentrantLock();

public void increase() {
lock.lock();
try {
inc++;
} finally{
lock.unlock();
}
}

public static void main(String[] args) {
final Test test = new Test();
for(int i=0;i<10;i++){
new Thread(){
public void run() {
for(int j=0;j<1000;j++)
test.increase();
};
}.start();
}

while(Thread.activeCount()>1) //保证前面的线程都执行完
Thread.yield();
System.out.println(test.inc);
}
}

下面这个例子很好:

每次运行的结果都可能不一致,因为volatile 并不保证语句的原子性,比如自增操作分为两步:一步读取、一步改写,在读取之后并不进行改写操作。

public class Test {
public volatile int inc = 0;

public void increase() {
inc++;
}

public static void main(String[] args) {
final Test test = new Test();
for(int i=0;i<10;i++){
new Thread(){
public void run() {
for(int j=0;j<1000;j++)
test.increase();
};
}.start();
}

while(Thread.activeCount()>1) //保证前面的线程都执行完
Thread.yield();
System.out.println(test.inc);
}
}
加上同步或者锁的机制,则不存在什么问题了。

public class Test {
public int inc = 0;

public synchronized void increase() {
inc++;
}

public static void main(String[] args) {
final Test test = new Test();
for(int i=0;i<10;i++){
new Thread(){
public void run() {
for(int j=0;j<1000;j++)
test.increase();
};
}.start();
}

while(Thread.activeCount()>1) //保证前面的线程都执行完
Thread.yield();
System.out.println(test.inc);
}
}