volatile关键字

关于volatile关键字,下列描述不正确的是?

正确答案: B D   你的答案: A C (错误)

用volatile修饰的变量,每次更新对其他线程都是立即可见的。
对volatile变量的操作是原子性的。
对volatile变量的操作不会造成阻塞。
不依赖其他锁机制,多线程环境下的计数器可用volatile实现。
 
  
 
  
 
  

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

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

2)禁止进行指令重排序。

volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。

而对该变量的修改,volatile并不提供原子性的保证。

由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况

多线程下计数器必须使用锁保护。

   
   
所谓  volatile的措施,就是
1. 每次从内存中取值,不从缓存中什么的拿值。这就保证了用  volatile修饰的共享变量,每次的更新对于其他线程都是可见的。
2.  volatile保证了其他线程的立即可见性,就没有保证原子性。
3.由于有些时候对  volatile的操作,不会被保存,说明不会造成阻塞。不可用与多线程环境下的计数器。
   
   
原理:

当一个变量被定义为volatile之后,就可以保证此变量对所有线程的可见性,即当一个线程修改了此变量的值的时候,变量新的值对于其他线程来说是可以立即得知的。可以理解成:对volatile变量所有的写操作都能立刻被其他线程得知。但是这并不代表基于volatile变量的运算在并发下是安全的,因为volatile只能保证内存可见性,却没有保证对变量操作的原子性。比如下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
 * 发起20个线程,每个线程对race变量进行10000次自增操作,如果代码能够正确并发,
 * 则最终race的结果应为200000,但实际的运行结果却小于200000。
 *
 * @author Colin Wang
 *
 */
public class VolatileTest {
    public static volatile int race = 0;
 
    public static void increase() {
        race++;
    }
 
    private static final int THREADS_COUNT = 20;
 
    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_COUNT];
 
        for (int i = 0; i < THREADS_COUNT; i++) {
            threads[i] = new Thread(new Runnable() {
 
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) {
                        increase();
                    }
                }
            });
            threads[i].start();
        }
         
        while (Thread.activeCount() > 1)
            Thread.yield();
 
        System.out.println(race);
    }
}

这便是因为race++操作不是一个原子操作,导致一些线程对变量race的修改丢失

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值