所谓的原子量即操作变量的操作是“原子的”,该操作不可再分,因此是线程安全的。

为何要使用原子变量呢,原因是多个线程对单个变量操作也会引起一些问题。在Java5之前,可以通过volatile、synchronized关键字来解决并发访问的安全问题,但这样太麻烦。

Java5之后,专门提供了用来进行单变量多线程并发安全访问的工具包java.util.concurrent.atomic,其中的类也很简单。

packagecn.thread;importjava.util.concurrent.atomic.AtomicLong;public class AtomicRunnable implementsRunnable {private static AtomicLong aLong = new AtomicLong(10000); //原子量,每个线程都可以自由操作

private String name; //操作人

private int x; //操作数额

AtomicRunnable(String name,intx) {this.name =name;this.x =x;

}public voidrun() {

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

}

}

packagecn.thread;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.atomic.AtomicLong;/*** 多线程-原子量

*

*@author林计钦

*@version1.0 2013-7-26 下午04:13:45*/

public classThreadAtomicTest {public static voidmain(String[] args) {

ExecutorService pool= Executors.newFixedThreadPool(2);

Runnable t1= new AtomicRunnable("张三", 2000);

Runnable t2= new AtomicRunnable("李四", 3600);

Runnable t3= new AtomicRunnable("王五", 2700);

Runnable t4= new AtomicRunnable("老张", 600);

Runnable t5= new AtomicRunnable("老牛", 1300);

Runnable t6= new AtomicRunnable("胖子", 800);//执行各个线程

pool.execute(t1);

pool.execute(t2);

pool.execute(t3);

pool.execute(t4);

pool.execute(t5);

pool.execute(t6);//关闭线程池

pool.shutdown();

}

}

运行结果:

张三执行了2000,当前余额:12000王五执行了2700,当前余额:14700老张执行了600,当前余额:15300老牛执行了1300,当前余额:16600胖子执行了800,当前余额:17400李四执行了3600,当前余额:21000

张三执行了2000,当前余额:12000李四执行了3600,当前余额:15600老张执行了600,当前余额:18900老牛执行了1300,当前余额:20200胖子执行了800,当前余额:21000王五执行了2700,当前余额:18300

张三执行了2000,当前余额:12000王五执行了2700,当前余额:14700李四执行了3600,当前余额:18300老牛执行了1300,当前余额:20200胖子执行了800,当前余额:21000老张执行了600,当前余额:18900

从运行结果可以看出,虽然使用了原子量,但是程序并发访问还是有问题,那究竟问题出在哪里了?

这里要注意的一点是,原子量虽然可以保证单个变量在某一个操作过程的安全,但无法保证你整个代码块,或者整个程序的安全性。因此,通常还应该使用锁等同步机制来控制整个程序的安全性。

下面是对这个错误修正:

packagecn.thread;importjava.util.concurrent.atomic.AtomicLong;importjava.util.concurrent.locks.Lock;public class AtomicRunnable2 implementsRunnable {private static AtomicLong aLong = new AtomicLong(10000); //原子量,每个线程都可以自由操作

private String name; //操作人

private int x; //操作数额

privateLock lock;

AtomicRunnable2(String name,intx, Lock lock) {this.name =name;this.x =x;this.lock=lock;

}public voidrun() {

lock.lock();

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

lock.unlock();

}

}

packagecn.thread;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.atomic.AtomicLong;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/*** 多线程-原子量

*

*@author林计钦

*@version1.0 2013-7-26 下午04:13:45*/

public classThreadAtomicTest2 {public static void main(String[] args) throwsInterruptedException {

ExecutorService pool= Executors.newFixedThreadPool(2);

Lock lock= new ReentrantLock(false);

Runnable t1= new AtomicRunnable2("张三", 2000, lock);

Runnable t2= new AtomicRunnable2("李四", 3600, lock);

Runnable t3= new AtomicRunnable2("王五", 2700, lock);

Runnable t4= new AtomicRunnable2("老张", 600, lock);

Runnable t5= new AtomicRunnable2("老牛", 1300, lock);

Runnable t6= new AtomicRunnable2("胖子", 800, lock);//执行各个线程

pool.execute(t1);

pool.execute(t2);

pool.execute(t3);

pool.execute(t4);

pool.execute(t5);

pool.execute(t6);//关闭线程池

pool.shutdown();

}

}

运行结果:

李四执行了3600,当前余额:13600王五执行了2700,当前余额:16300老张执行了600,当前余额:16900老牛执行了1300,当前余额:18200胖子执行了800,当前余额:19000张三执行了2000,当前余额:21000

这里使用了一个对象锁,来控制对并发代码的访问。不管运行多少次,执行次序如何,最终余额均为21000,这个结果是正确的。

有关原子量的用法很简单,关键是对原子量的认识,原子仅仅是保证变量操作的原子性,但整个程序还需要考虑线程安全的。

java 原子量_Java多线程-新特征-原子量相关推荐

  1. java 原子量_Java線程:新特征-原子量

    所謂的原子量即操作變量的操作是"原子的",該操作不可再分,因此是線程安全的. 為何要使用原子變量呢,原因是多個線程對單個變量操作也會引起一些問題.在Java5之前,可以通過vola ...

  2. Java多线程-新特征-阻塞队列ArrayBlockingQueue

    阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...

  3. 什么是java线程_Java多线程是什么意思?

    展开全部 Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多636f707932313 ...

  4. java 模块化_Java 9 新特性 - 模块化 - Java 技术驿站-Java 技术驿站

    Java 9 最大的特性就是模块化 ( Module ) 了.本章,我们就对这个 模块化 进行一些简单的讲解,包括 Java 9 模块化的概念.如何实现.如何使用等 对于 Java 9 来说,模块化 ...

  5. java check word lock_Java多线程-新特征-锁(下)

    在上文中提到了Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁.为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控 ...

  6. 多线程 java 实例_Java多线程实例学习

    1. Java多线程的就绪.运行和死亡状态 就绪状态转换为运行状态:当此线程得到处理器资源: 运行状态转换为就绪状态:当此线程主动调用yield()方法或在运行过程中失去处理器资源. 运行状态转换为死 ...

  7. java厨房_Java多线程基础

    目录: 进程和线程 为什么使用多线程? 多线程的创建方式 Runnable与Thread两种方式比较 start()与run()方法 线程的生命周期/状态转换 常用方法使用与解读 线程的优先级 守护线 ...

  8. java丐帮_java多线程学习笔记(五)

    补充一个synchronized关键字的结论: 线程A先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法 A线程现持有object对 ...

  9. java丐帮_java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现"脏读"的现象,这个时候需要"临界区"的出现去解决多 ...

  10. java 计时器_Java多线程并发容器之并发倒计时器

    从火箭发场景来学习Java多线程并发闭锁对象 倒计时器场景 在我们开发过程中,有时候会使用到倒计时计数器.最简单的是:int size = 5; 执行后,size-这种方式来实现.但是在多线程并发的情 ...

最新文章

  1. 滴滴业务研发的精益实践
  2. 2013 全国高校计算机等级考试(广西考区)一级笔试试题,全国高校计算机等级考试(广西考区)一级笔试试题卷.PDF...
  3. springcloud 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
  4. html地图缩放比例,百度地图之添加控件——比例尺、缩略图、平移缩放
  5. 《快学Scala》勘误
  6. 马斯克:如果我不担任CEO 特斯拉就会完蛋
  7. Windows Phone开发(18):变形金刚第九季——变换 转:http://blog.csdn.net/tcjiaan/article/details/7385056...
  8. Centos7安装Python3的方法
  9. 147 · 水仙花数
  10. 老李分享:5个衡量软件质量的标准
  11. OpenCV中对Mat里面depth,dims,channels,step,data,elemSize和数据地址计算的理解
  12. WebCollector 网页正文快速提取
  13. Bootstrap横屏后竖屏
  14. 网络七层协议,一张图片告诉你
  15. 如何用SolidWorks软件绘制三维模型?
  16. 一键获取graphpad同款主题
  17. 坐标旋转变换 公式图解
  18. 三阶魔方7步还原法详解 简单
  19. 小信号放大运算放大器使用要依照三步骤,4个细节更重要
  20. Java实现旅行商问题

热门文章

  1. php项目权限系统设计
  2. 计算机综述(computer overview)
  3. 常用Windows 运行命令
  4. Casper与V神的博弈论(过节了,文末送大礼)
  5. 综合影响力模型InfG算法
  6. JAVAweb开发中Ajax教程
  7. northwind数据库介绍
  8. Android 应用开发---TextView(文本框)详解
  9. 计算机桌面上的图标如何删除,怎么删除电脑桌面上的图标啊?
  10. Python pyqt5绘画界面(文章可能啰嗦,不喜勿喷)