AtomicLong

当我们需要在多线程中统计线程执行次数,需要一个累加器,下面的demo,一次开启100个线程,可以看到“64”打印了两次(不知道什么原因,我在linux环境下,效果比win10好很多,这里只冲突了一个线程)

    public static Long count = new Long(0);

    public static Long accumulator(){
        return ++count;
    }

    public static void main(String[] args) {

        for(int i =0 ;i< 100;i++){
            new Thread(()->{
                System.out.println("get Cumulative permissions:"+accumulator());
            }).start();
        }
    }

// 控制台打印

get Cumulative permissions:1
get Cumulative permissions:2
get Cumulative permissions:4
get Cumulative permissions:3
get Cumulative permissions:5
get Cumulative permissions:6
get Cumulative permissions:7
get Cumulative permissions:8
get Cumulative permissions:9
get Cumulative permissions:10
get Cumulative permissions:12
get Cumulative permissions:11
get Cumulative permissions:15
get Cumulative permissions:14
get Cumulative permissions:13
get Cumulative permissions:16
get Cumulative permissions:17
get Cumulative permissions:18
get Cumulative permissions:19
get Cumulative permissions:20
get Cumulative permissions:21
get Cumulative permissions:22
get Cumulative permissions:23
get Cumulative permissions:24
get Cumulative permissions:25
get Cumulative permissions:26
get Cumulative permissions:27
get Cumulative permissions:28
get Cumulative permissions:29
get Cumulative permissions:30
get Cumulative permissions:32
get Cumulative permissions:33
get Cumulative permissions:34
get Cumulative permissions:35
get Cumulative permissions:36
get Cumulative permissions:39
get Cumulative permissions:40
get Cumulative permissions:41
get Cumulative permissions:31
get Cumulative permissions:38
get Cumulative permissions:37
get Cumulative permissions:42
get Cumulative permissions:43
get Cumulative permissions:44
get Cumulative permissions:45
get Cumulative permissions:46
get Cumulative permissions:47
get Cumulative permissions:50
get Cumulative permissions:49
get Cumulative permissions:48
get Cumulative permissions:51
get Cumulative permissions:52
get Cumulative permissions:53
get Cumulative permissions:55
get Cumulative permissions:56
get Cumulative permissions:54
get Cumulative permissions:57
get Cumulative permissions:60
get Cumulative permissions:59
get Cumulative permissions:58
get Cumulative permissions:61
get Cumulative permissions:62
get Cumulative permissions:63
get Cumulative permissions:64
get Cumulative permissions:65
get Cumulative permissions:64
get Cumulative permissions:66
get Cumulative permissions:67
get Cumulative permissions:68
get Cumulative permissions:69
get Cumulative permissions:70
get Cumulative permissions:71
get Cumulative permissions:72
get Cumulative permissions:73
get Cumulative permissions:74
get Cumulative permissions:75
get Cumulative permissions:76
get Cumulative permissions:77
get Cumulative permissions:80
get Cumulative permissions:79
get Cumulative permissions:78
get Cumulative permissions:81
get Cumulative permissions:83
get Cumulative permissions:84
get Cumulative permissions:82
get Cumulative permissions:85
get Cumulative permissions:86
get Cumulative permissions:87
get Cumulative permissions:88
get Cumulative permissions:89
get Cumulative permissions:90
get Cumulative permissions:91
get Cumulative permissions:92
get Cumulative permissions:93
get Cumulative permissions:94
get Cumulative permissions:95
get Cumulative permissions:96
get Cumulative permissions:97
get Cumulative permissions:98
get Cumulative permissions:99
Disconnected from the target VM, address: '127.0.0.1:44469', transport: 'socket'

Process finished with exit code 0

因为每个线程对于变量的操作在多线程间不是原子级别的操作,为了解决这种问题的出现,在jdk中提供了一些针对基础类型的解决办法,例如:AtomicLong,AtomicInteger:
这个时候我们把上面的代码进行优化,替换计数器的类型:

    public static AtomicLong count = new AtomicLong(0);

    public static Long accumulator(){
        return count.incrementAndGet();
    }

    public static void main(String[] args) {

        for(int i =0 ;i< 100;i++){
            new Thread(()->{
                System.out.println("get Cumulative permissions:"+accumulator());
            }).start();
        }
    }
   \\ 控制台打印
   get Cumulative permissions:1
get Cumulative permissions:2
get Cumulative permissions:3
get Cumulative permissions:4
get Cumulative permissions:5
get Cumulative permissions:6
get Cumulative permissions:7
get Cumulative permissions:8
get Cumulative permissions:9
get Cumulative permissions:10
get Cumulative permissions:11
get Cumulative permissions:12
get Cumulative permissions:13
get Cumulative permissions:14
get Cumulative permissions:15
get Cumulative permissions:16
get Cumulative permissions:17
get Cumulative permissions:19
get Cumulative permissions:18
get Cumulative permissions:20
get Cumulative permissions:21
get Cumulative permissions:22
get Cumulative permissions:23
get Cumulative permissions:24
get Cumulative permissions:25
get Cumulative permissions:26
get Cumulative permissions:27
get Cumulative permissions:28
get Cumulative permissions:29
get Cumulative permissions:31
get Cumulative permissions:30
get Cumulative permissions:32
get Cumulative permissions:33
get Cumulative permissions:34
get Cumulative permissions:35
get Cumulative permissions:36
get Cumulative permissions:37
get Cumulative permissions:38
get Cumulative permissions:39
get Cumulative permissions:40
get Cumulative permissions:41
get Cumulative permissions:42
get Cumulative permissions:43
get Cumulative permissions:44
get Cumulative permissions:45
get Cumulative permissions:46
get Cumulative permissions:47
get Cumulative permissions:49
get Cumulative permissions:71
get Cumulative permissions:48
get Cumulative permissions:76
get Cumulative permissions:75
get Cumulative permissions:74
get Cumulative permissions:73
get Cumulative permissions:72
get Cumulative permissions:70
get Cumulative permissions:66
get Cumulative permissions:69
get Cumulative permissions:68
get Cumulative permissions:67
get Cumulative permissions:65
get Cumulative permissions:64
get Cumulative permissions:63
get Cumulative permissions:62
get Cumulative permissions:61
get Cumulative permissions:60
get Cumulative permissions:59
get Cumulative permissions:77
get Cumulative permissions:54
get Cumulative permissions:57
get Cumulative permissions:58
get Cumulative permissions:56
get Cumulative permissions:52
get Cumulative permissions:55
get Cumulative permissions:53
get Cumulative permissions:51
get Cumulative permissions:50
get Cumulative permissions:78
get Cumulative permissions:79
get Cumulative permissions:80
get Cumulative permissions:81
get Cumulative permissions:82
get Cumulative permissions:83
get Cumulative permissions:84
get Cumulative permissions:85
get Cumulative permissions:86
get Cumulative permissions:88
get Cumulative permissions:87
get Cumulative permissions:93
get Cumulative permissions:92
get Cumulative permissions:91
get Cumulative permissions:90
get Cumulative permissions:94
get Cumulative permissions:89
get Cumulative permissions:95
get Cumulative permissions:96
get Cumulative permissions:97
get Cumulative permissions:98
get Cumulative permissions:99
get Cumulative permissions:100

很明显最重要的一个方法是累加器的incrementAndGet()方法:

    public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
    }

	// 自旋判断
    public final long getAndAddLong(Object var1, long var2, long var4) { //var1:初始值对象,var2:偏移量,var4
        long var6;
        do {
            var6 = this.getLongVolatile(var1, var2);//var6:对应的共享内存中的 value 值
        } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

        return var6;
    }

public native long getLongVolatile(Object var1, long var2);

unsafe
又出现了一个新的方法:unsafe,直接翻译出来就是“不安全的”,因为java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,所以unsafe的native方法的具体实现我们不太容易看到。
valueOffset偏移量
从代码可以看出来,在getAndAddLong方法里的var1是初始值对象,通过偏移量获得对应的共享内存中的 value 值,拿期望的值和原本的一个值作比较,如果一样则更新,不一样则自旋判断(CAS)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值