volatile 关键字

volatile 关键字(volatile:易变的,反复无常的)

声明此变量值是不稳定的,每次使用它都到主存中进行读取,而且当成员变量发生变化时,强迫线程将变化值回写到共享内存中。且不会将该变量上的操作与其他内存操作一起重排序。
volatile 是一种 synchronized 的简化,他并不会执行加锁操作,所以不会阻塞执行线程。
volatile 只确保每线程执行时从主内存拿数据,而不能使用自己的缓存。但由于没有使用锁机制,因此不能保证更新主内存中的值的时候是线程安全的。如 volatile a=5,两个线程同时执行 a++操作,当他们从主内存拿数据时,都是拿出来的5,线程1执行完+1后,将6覆盖主内存中的a,此时线程2也同时加1后用6覆盖主内存中的1,所以当两个线程都执行完毕后,主内存中的 a=6,而非我们希望看到的 a=7。

因此,需要线程绝对安全时,只使用 volatile 是绝对不行的,还是要用 synchronized 同步。但 volatile 由于没有使用锁,因此执行效率要比 synchronized 高很多。

write by 开发老张

例:

package com.zsoft.test;

/**
 * 测试 Volatile 和 synchronized 的线程安全差别
 * @author zsoft
 *
 */
public class VolatileAndSyncTest {
	public volatile static int count=0;

	public static void inc(){
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		count++;
	}

	public synchronized static void incBySync(){
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		count++;
	}

	public static void main(String[] args) {
		for(int i=0;i<1000;i++){
			new Thread(new Runnable() {
			
				@Override
				public void run() {
					//VolatileAndSyncTest.inc();		//非同步方法
					VolatileAndSyncTest.incBySync();	//同步方法
				}
			}).start();
		}
	
		try {
			Thread.sleep(1200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("运行结果:VolatileAndSyncTest.count="+VolatileAndSyncTest.count);
	}

}


结果:
执行 VolatileAndSyncTest.inc(); 方法时,结果总是随机的,基本得不到期望的1000,总是993,995之类的随机结果
执行 VolatileAndSyncTest.incBySync(); 方法时,由于使用了同步机制,因此可以保证结果是我们想要的1000,但由于各个线程排队执行,也就基本上失去了多线程并发执行的优势,执行效率很低。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值