java学习笔记91--原子操作

1.定义
        原子操作(atomic operation)是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程切换。

    2.非原子操作i++
        在Java里面,++i(i++)或者--i(i--)不是线程安全的,这里面有三个独立的操作:获得变量当前值,为该值+1/-1,然后写回新的值. 通常情况下,只能使用加锁才能保证读-改-写这三个操作是"原子性"的。也就是说我们平时所用的i++等操作是非原子操作,一般的需要加锁才能保证其"原子性"
        例如:
        public static void main(String[] args) {
            class Run implements Runnable{
                private int i;
                public void run() {
                    for(int j=0;j<100000;j++){
                        i++;
                    }
                }
                public int getValue(){
                    return this.i;
                }
            };
            
            Run run = new Run();
            Thread t1 = new Thread(run);
            Thread t2 = new Thread(run);
            Thread t3 = new Thread(run);
            Thread t4 = new Thread(run);
            
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            
            try {
                t1.join();
                t2.join();
                t3.join();
                t4.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            System.out.println("i = "+run.getValue());
        }

        注:4个线程分别运行for循环10万次,每次i++,i是共享变量,那么最终i的值应该是40万,但是因为i++并非原子操作,所以最终结果也不一定是40万。

        注:这里即使使用了volatile修饰共享变量i,也是不行的,因为volatile只是强制线程去主内存中取值和存值,而不能保证i++操作的原子性


    3.加锁可以保证i++的原子性
        例如:
        public static void main(String[] args) {
            class Run implements Runnable{
                private int i;
                public void run() {
                    for(int j=0;j<100000;j++){
                        i++;
                    }
                }
                public int getValue(){
                    return this.i;
                }
            };
            
            Run run = new Run();
            Thread t1 = new Thread(run);
            Thread t2 = new Thread(run);
            Thread t3 = new Thread(run);
            Thread t4 = new Thread(run);
            
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            
            try {
                t1.join();
                t2.join();
                t3.join();
                t4.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            System.out.println("i = "+run.getValue());
        }

    
    4.原子操作类
        JDK5.0提供了一组atomic-class来帮助我们简化同步处理。基本工作原理是使用了同步synchronized的方法实现了对一个long, int等类型值的增、减、赋值(更新)操作.
        java.util.concurrent.atomic.AtomicXxxxx类
        这些类都是类似的使用方法,这里以AtomicInteger为例:
            i.get()就是获得该对象对应的int值
            i.incrementAndGet() 类似于 ++i
            i.getAndIncrement() 类似于 i++
            i.getAndDecrement() 类似于 i--
            i.decrementAndGet() 类似于 --i
        
        例如:上面的例子可以修改如下
        public static void main(String[] args) {
            class Run implements Runnable{
                private AtomicInteger i = new AtomicInteger(0);
                public void run() {
                    for(int j=0;j<100000;j++){
                        i.incrementAndGet();
                    }
                }
                public int getValue(){
                    return i.get();
                }
            };
            
            Run run = new Run();
            Thread t1 = new Thread(run);
            Thread t2 = new Thread(run);
            Thread t3 = new Thread(run);
            Thread t4 = new Thread(run);
            
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            
            try {
                t1.join();
                t2.join();
                t3.join();
                t4.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            System.out.println("i = "+run.getValue());
        }
        
        注:保证操作的原子性,每次运行后的结果都是40万

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值