知识大全 关于Java自增操作的原子性
Posted 操作
篇首语:幼敏悟过人,读书辄成诵。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 关于Java自增操作的原子性相关的知识,希望对你有一定的参考价值。
关于Java自增操作的原子性 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
最近在工作中和一个同事因为自增是不是原子性操作争论的面红耳赤 那Java的自增操作到底是不是原子性操作呢 答案是否的 即Java的自增操作不是原子性操作 首先我们先看看Bruce Eckel是怎么说的 In the JVM an increment is not atomic and involves both a read and a write (via the latest Java Performance Tuning Newsletter) 意思很简单 就是说在jvm中自增不是原子性操作 它包含一个读操作和一个写操作 以上可能还不能让你信服 要想让人心服口服 就必须用代码说话 正如FaceBook的文化一样 代码赢得争论 那我们就看一段代码 以下的代码是用 个线程同时执行自增操作 每个线程自增 次 如果自增操作是原子性操作的话 那么执行完amount的值为 运行代码之后 你会发现amount的值小于 这就说明自增操作不是原子性的 /** * * @author renrun wu */ public class MultiThread implements Runnable private int count; private int amount = ; public MultiThread() count = ; public MultiThread(int count) unt = count; @Override public void run() for (int i = ; i < count; i++) amount++; public static void main(String[] args) ExecutorService executorService = Executors newCachedThreadPool() MultiThread multiThread =new MultiThread() for (int i = ; i < ; i++) executorService execute(multiThread) executorService shutdown() try Thread sleep( ) catch (InterruptedException e) e printStackTrace() System out println(multiThread amount) 如果以上还不能让你信服的话 也没关系 我们就把自增操作反编译出来 看看java字节码是怎么操作的 以下是一个简单的自增操作代码 public class Increment private int id = ; public void getNext() id++; 我们看看反编译之后的Java字节码 主要关注getNext()方法内部的Java字节码 public class Increment extends java lang Object public Increment() Code: : aload_ : invokespecial # ; //Method java/lang/Object <init> :()V : aload_ : iconst_ : putfield # ; //Field id:I : return public void getNext() Code: : aload_ //加载局部变量表index为 的变量 在这里是this : dup //将当前栈顶的对象引用复制一份 : getfield # ; //Field id:I 获取id的值 并将其值压入栈顶 : iconst_ //将int型的值 压入栈顶 : iadd //将栈顶两个int类型的元素相加 并将其值压入栈顶 : putfield # ; //Field id:I 将栈顶的值赋值给id : return 很明显 我们能够看到在getNext()方法内部 对于类变量id有一个先取值后加一再赋值的过程 因此 我们可以很肯定的说Java中的自增操作不是原子性的 也许你会问 那局部变量的自增操作是否是原子性的 好 我们在看看一下代码 public class Increment public void getNext() int id = ; id++; 我们再看看反编译之后的Java字节码 主要还是关注getNext()方法内部的Java字节码 public class Increment extends java lang Object public Increment() Code: : aload_ : invokespecial # ; //Method java/lang/Object <init> :()V : return public void getNext() Code: : iconst_ : istore_ : iinc : return 与全局变量的自增操作相比 很明显局部变量的自增操作少了getfield与putfield操作 而且对于局部变量来说 它无论如何都不会涉及到多线程的操作 因此局部变量的自增操作是否是原子操作也就显得不那么重要了 cha138/Article/program/Java/hx/201311/26944相关参考
如何保证并发下资料库操作的原子性不并发控制的话会带来一系列问题:资料冗余、更新异常、插入异常、删除异常等并发控制保证事务4个特性,acid:A:原子性(Atomicity)事务是资料库的逻辑工作单位,
一般服务器端代码每次收到一个线程一个client就会产生 /************************开始监听**************************/ intport=;
知识大全 Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类
Java多线程系列--“JUC原子类”05之AtomicLongFieldUpdater原子类 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整
自己编写的Java数组操作工具 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 看到网上的一段关于
再谈通过Java执行POST操作 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 我的上一篇关于从
Java多线程之Atomic:原子变量与原子类 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一
1清除本地数据 ls_sql=TRUNCATETABLE+ls_table[] executeIMMEDIATE:ls_sqlusingsqlca; 2//打开可以插入自增显示插入自
Oracle使用触发器实现自增ID 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! userinf
Oracle没有自增字段这样的功能但是通过触发器(trigger)和序列(sequence)可以实现 先建一个测试表了 createtableuserlogin( id  
本篇文章是对常用数据库的自增字段创建方法进行了全面的汇总介绍需要的朋友参考下 DB复制代码代码如下:CREATE TABLE T(