Volatile

一、volatile

volatile 是一个类型修饰符。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略。

二、volatile 的特性

①保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)

class ThreadVolatileDemo extends Thread {
    //不用volatile修饰flag的话,虽然主线程中设置flag为
    //false,也不会使程序停止运行,因为 threadVolatileDemo子线程
    //一直读取的是本地内存(主内存没将flag还是true的副本),这样子
    //线程一直在执行while循环。
    //使用Volatile关键字将强制线程每次读取该值的时候都去主内存中取值
	public volatile boolean flag = true;
	@Override
	public void run() {
		System.out.println("开始执行子线程....");
		while (flag) {
		}
		System.out.println("线程停止");
	}
	public void setRuning(boolean flag) {
		this.flag = flag;
	}

}


public class ThreadVolatile {
	public static void main(String[] args) throws InterruptedException {
		ThreadVolatileDemo threadVolatileDemo = new ThreadVolatileDemo();
		threadVolatileDemo.start();
		Thread.sleep(3000);
		threadVolatileDemo.setRuning(false);
		System.out.println("flag 已经设置成false");
		Thread.sleep(1000);
		System.out.println(threadVolatileDemo.flag);

	}
}

②禁止进行指令重排序。(实现有序性)

③volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。

class VolatileNoAtomic extends Thread {
	private static volatile int count = 0;
	

	@Override
	public void run() {
		//每个线程给共享资源count加1000
		for (int i = 0; i < 1000; i++) {
			count++;
		}
		System.out.println(getName() + "-----" + count);
	}

}

public class Demo001{
	public static void main(String[] args) {
		// 初始化10个线程
		VolatileNoAtomic[] volatileNoAtomic = new VolatileNoAtomic[10];
		for (int i = 0; i < 10; i++) {
			// 创建
			volatileNoAtomic[i] = new VolatileNoAtomic();
		}
		for (int i = 0; i < volatileNoAtomic.length; i++) {
			volatileNoAtomic[i].start();
		}
	}
}

使用开发包中的atomic解决:

class VolatileNoAtomic extends Thread {
	
	//private static volatile int count = 0;
	private static AtomicInteger count = new AtomicInteger(0);

	@Override
	public void run() {
		//每个线程给共享资源count加1000
		for (int i = 0; i < 1000; i++) {
			//count++;
			count.incrementAndGet();//就相当于count++
		}
		System.out.println(getName() + "-----" + count);
	}

}

public class Demo001{
	public static void main(String[] args) {
		// 初始化10个线程
		VolatileNoAtomic[] volatileNoAtomic = new VolatileNoAtomic[10];
		for (int i = 0; i < 10; i++) {
			// 创建
			volatileNoAtomic[i] = new VolatileNoAtomic();
		}
		for (int i = 0; i < volatileNoAtomic.length; i++) {
			volatileNoAtomic[i].start();
		}
	}
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值