volatile关键字
Java中提供了一种较弱的同步机制,即volatile关键字。可以把它看成是synchronized的轻量级实现,但是其并不能完全替代synchronized,或者说将其当做锁来使用。volatile具有可见性与有序性,但不具有原子性。即通过volatile修饰的共享变量(类的成员变量和静态成员变量)不直接存在于工作线程,而是存在于主内存中。线程每次读取时,都会去主内存中进行读取,从而保证其他线程每次对于该成员变量都能获取最新值。
简单来说,一个共享变量一旦被volatile修饰后,其就具备了两个特性:
1.保证多线程下对该变量的可见性。
2.保证多线程下对该变量的有序性。
volatile非原子性
public class AtomicityTest {
public volatile int inc = 0;
public void increment() {
for(int i=0;i<10000;i++){
inc++;
}
System.out.println(Thread.currentThread().getName()+"--->"+inc);
}
public static void main(String[] args) throws InterruptedException {
final AtomicityTest test = new AtomicityTest();
for(int i=0;i<10;i++){
new Thread(){
@Override
public void run() {
test.increment();
};
}.start();
}
}
}
由上面的结果可以看出volatile只能保证可见性,但不能保证原子性,而synchronized可以保证线程的可见性,也可以保证线程的原子性。
synchronized原子操作
public class AtomicityTest {
public int inc = 0;
public synchronized void increment() {
for(int i=0;i<10000;i++){
inc++;
}
System.out.println(Thread.currentThread().getName()+"--->"+inc);
}
public static void main(String[] args) throws InterruptedException {
AtomicityTest test = new AtomicityTest();
for(int i=0;i<10;i++){
new Thread(){
@Override
public void run() {
test.increment();
};
}.start();
}
}
}