JAVA多线程中,原子操作的概念——原子操作真的不需要进行同步控制吗?
来源:互联网 发布:个人记账软件 pc 编辑:程序博客网 时间:2024/05/18 23:25
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;class Sd implements Runnable {private int a = 1;public int getA() {return a;}private synchronized void oddIncrement() {a++;a++;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true) {oddIncrement();}}}public class SychronizedDemo {public static void main(String[] args) {ExecutorService es = Executors.newCachedThreadPool();Sd sd = new Sd();es.execute(sd);while(true) {int b = sd.getA();if(b%2==0) {System.out.println(b);System.exit(0);}}}}
程序中,我们可以看到,a的初始值是1,然后oddIncrement()操作是连续两次给a增值操作,那么一次调用就是+2,所以a无论经过多少次增值操作,它都是一个奇数,
那么我们在主函数中判断%2==0的这个操作,按道理说应该是不可能的,但是事实却是相反,仍然会有偶数的b值打印在控制台。
这就说明原子操作是需要同步控制的。那么上面的问题出在什么地方呢?
我认为是getA这个方法上,在getA和oddIncrement方法之间,绝对存在某些操作操作使得getA值和oddIncrement方法有了偏差。
虽然oddIncrement操作进行了同步,但是getA并没有进行同步。我们尝试对getA方法也进行同步
public synchronized int getA() {return a;}
当我们再次运行以上程序时,发现控制台久久没有输出了。
我想,这样应该就没有问题了。
所以说在JAVA程序中,看似简单的原子操作,增值,取值,貌似不会被别的程序所打断,但是事实却不是如此。
以上是通过synchronized这个关键字来同步原子操作的两个方法,那么有一种更简便的方法是,对所操作的属性用原子类来定义即可:
private AtomicInteger a = new AtomicInteger(1);public int getA() {return a.get();}private void oddIncrement() {a.addAndGet(2);}
个人链接:
--------------------------------
新浪微博:http://weibo.com/cwtree
--------------------------------
- JAVA多线程中,原子操作的概念——原子操作真的不需要进行同步控制吗?
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- 多线程程序中操作的原子性
- HDU1087--Super Jumping! Jumping! Jumping!
- ltib(3)在嵌入式系统中实现nfs服务器
- 游戏物体跟随鼠标移动
- ltib(4)实现telnet服务器/etc/securetty
- 关于水晶报表“已达到系统管理员的最大报表处理作业数限制”解决
- JAVA多线程中,原子操作的概念——原子操作真的不需要进行同步控制吗?
- 推荐一些Linux下常用的软件
- 2013寒假练习 1009:Number Sequence
- eclipse 安装hibernate 插件
- Request.UrlReferrer为空的解决
- jmap - Memory Map
- linux -- LTIB添加新平台
- Stock Chase hdu3357 图论
- 关于语言学习的想法