JDK1.5 AtomicLong实例

JDK1.5 AtomicLong****实例

类 AtomicLong

可以用原子方式更新的 long 值。有关原子变量属性的描述,请参阅 java.util.concurrent.atomic 包规范。AtomicLong 可用在应用程序中(如以原子方式增加的序列号),并且不能用于替换 Long。但是,此类确实扩展了 Number,允许那些处理基于数字类的工具和实用工具进行统一访问。

常见方法

long addAndGet(long delta):以原子方式将给定值与当前值相加。

boolean compareAndSet(long expect, long update):如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。

long decrementAndGet():以原子方式将当前值减 1。

double doubleValue():以 double 形式返回指定的数值。

float floatValue():以 float 形式返回指定的数值。

long get():获取当前值。

软件包 java.util.concurrent.atomic

类的小工具包,支持在单个变量上解除锁定的线程安全编程。

类摘要

AtomicBoolean

可以用原子方式更新的 boolean 值。

AtomicInteger

可以用原子方式更新的 int 值。

AtomicIntegerArray

可以用原子方式更新其元素的 int 数组。

AtomicIntegerFieldUpdater<T>

基于反射的实用工具,可以对指定类的指定 volatile int 字段进行原子更新。

AtomicLong

可以用原子方式更新的 long 值。

AtomicLongArray

可以用原子方式更新其元素的 long 数组。

AtomicLongFieldUpdater<T>

基于反射的实用工具,可以对指定类的指定 volatile long 字段进行原子更新。

AtomicMarkableReference<V>

AtomicMarkableReference 维护带有标记位的对象引用,可以原子方式对其进行更新。

AtomicReference<V>

可以用原子方式更新的对象引用。

AtomicReferenceArray<E>

可以用原子方式更新其元素的对象引用数组。

AtomicReferenceFieldUpdater<T,V>

基于反射的实用工具,可以对指定类的指定 volatile reference 字段进行原子更新。

AtomicStampedReference<V>

AtomicStampedReference 维护带有整数“标志”的对象引用,可以原子方式对其进行更新。

实例1:

Java代码    收藏代码

  1. package com.bijian.thread;

  2. import java.util.concurrent.atomic.AtomicLong;

  3. import java.util.concurrent.locks.Lock;

  4. public class MyRunnable implements Runnable {

  5. private static AtomicLong aLong = new AtomicLong(10000); // 原子量,每个线程都可以自由操作

  6. private String name; // 操作人

  7. private int x; // 操作数额

  8. private Lock lock;

  9. MyRunnable(String name, int x, Lock lock) {

  10. this.name = name;

  11. this.x = x;

  12. this.lock = lock;

  13. }

  14. public void run() {

  15. System.out.println(name + "执行了" + x + ",当前余额:" + aLong.addAndGet(x));

  16. aLong.addAndGet(1);

  17. }

  18. }

Java代码    收藏代码

  1. package com.bijian.thread;

  2. import java.util.concurrent.ExecutorService;

  3. import java.util.concurrent.Executors;

  4. import java.util.concurrent.locks.Lock;

  5. import java.util.concurrent.locks.ReentrantLock;

  6. public class Main {

  7. public static void main(String[] args) {

  8. ExecutorService pool = Executors.newFixedThreadPool(2);

  9. Lock lock = new ReentrantLock(false);

  10. Runnable t1 = new MyRunnable("张三", 2000, lock);

  11. Runnable t2 = new MyRunnable("李四", 3600, lock);

  12. Runnable t3 = new MyRunnable("王五", 2700, lock);

  13. Runnable t4 = new MyRunnable("老张", 600, lock);

  14. Runnable t5 = new MyRunnable("老牛", 1300, lock);

  15. Runnable t6 = new MyRunnable("胖子", 800, lock);

  16. // 执行各个线程

  17. pool.execute(t1);

  18. pool.execute(t2);

  19. pool.execute(t3);

  20. pool.execute(t4);

  21. pool.execute(t5);

  22. pool.execute(t6);

  23. // 关闭线程池

  24. pool.shutdown();

  25. }

  26. }

运行结果:

Text代码    收藏代码

  1. 李四执行了3600,当前余额:13600
  2. 张三执行了2000,当前余额:15600
  3. 王五执行了2700,当前余额:18302
  4. 老张执行了600,当前余额:18903
  5. 老牛执行了1300,当前余额:20203
  6. 胖子执行了800,当前余额:21004

**应该是每个线程执行后都会执行aLong.addAndGet(1);****语句,但实际结果却不是这样的,原因是:虽然long addAndGet(long delta)**方法是以原子方式将给定值与当前值相加,但两条两句在一块,也只能表示它们各自的执行是原子级的,它们作为一个整体却不是原子级的。

于是,我们稍微修改一下MyRunnable类,给它加上锁,即可达到我们预想的目的,如下实例2所示。

实例2(修改MyRunnable类):

Java代码    收藏代码

  1. package com.bijian.thread;

  2. import java.util.concurrent.atomic.AtomicLong;

  3. import java.util.concurrent.locks.Lock;

  4. public class MyRunnable implements Runnable {

  5. private static AtomicLong aLong = new AtomicLong(10000); // 原子量,每个线程都可以自由操作

  6. private String name; // 操作人

  7. private int x; // 操作数额

  8. private Lock lock;

  9. MyRunnable(String name, int x, Lock lock) {

  10. this.name = name;

  11. this.x = x;

  12. this.lock = lock;

  13. }

  14. public void run() {

  15. lock.lock();

  16. System.out.println(name + "执行了" + x + ",当前余额:" + aLong.addAndGet(x));

  17. aLong.addAndGet(1);

  18. lock.unlock();

  19. }

  20. }

运行结果:

Text代码    收藏代码

  1. 张三执行了2000,当前余额:12000
  2. 李四执行了3600,当前余额:15601
  3. 王五执行了2700,当前余额:18302
  4. 老张执行了600,当前余额:18903
  5. 胖子执行了800,当前余额:19704
  6. 老牛执行了1300,当前余额:21005
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )