`

int变量操作与线程安全

    博客分类:
  • java
阅读更多

    今天人人的笔试题目中有一个int i=0;i=i++;是否是线程安全的?如果不是说出在JVM中的执行步骤,以及使用JDK的什么类能够使线程安全些? JDk中的类是AtomicInteger,我答个Integer,哎,悲剧。

 

    文章出处:http://blog.sina.com.cn/s/blog_0d37403b0100xz0t.html

 

    AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。 来看AtomicInteger提供的接口。

 

//获取当前的值

public final int get()

//取当前的值,并设置新的值

 public final int getAndSet(int newValue)

//获取当前的值,并自增

 public final int getAndIncrement()

//获取当前的值,并自减

public final int getAndDecrement()

//获取当前的值,并加上预期的值

public final int getAndAdd(int delta)

... ...

我们在上一节提到的CAS主要是这两个方法

    public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    public final boolean weakCompareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

 

    这两个方法是名称不同,但是做的事是一样的,可能在后续的java版本里面会显示出区别来。

详细查看会发现,这两个接口都是调用一个unsafe的类来操作,这个是通过JNI实现的本地方法,细节就不考虑了。

 

下面是一个对比测试,我们写一个synchronized的方法和一个AtomicInteger的方法来进行测试,直观的感受下性能上的差异

 

package zl.study.concurrency;   
import java.util.concurrent.atomic.AtomicInteger;   
public class AtomicIntegerCompareTest {   
    private int value;   
       
    public AtomicIntegerCompareTest(int value){   
        this.value = value;   
    }   
       
    public synchronized int increase(){   
        return value++;   
    }   
       
    public static void main(String args[]){   
        long start = System.currentTimeMillis();   
           
        AtomicIntegerCompareTest test = new AtomicIntegerCompareTest(0);   
        for( int i=0;i< 1000000;i++){   
            test.increase();   
        }   
        long end = System.currentTimeMillis();   
        System.out.println("time elapse:"+(end -start));   
           
        long start1 = System.currentTimeMillis();   
           
        AtomicInteger atomic = new AtomicInteger(0);   
           
        for( int i=0;i< 1000000;i++){   
            atomic.incrementAndGet();   
        }   
        long end1 = System.currentTimeMillis();   
        System.out.println("time elapse:"+(end1 -start1) );   
           
           
    }   
}   
结果

time elapse:31
time elapse:16

 

 

    由此不难看出,通过JNI本地的CAS性能远超synchronized关键字

分享到:
评论

相关推荐

    Qt多线程通信 附源码demo

    Qt线程间共享数据主要有两种方式: ...1、传递int参数(主线程与子线程) 2、传递自定义参数(主线程与子线程) 3、传递自定义参数(子线程与子线程) 4、传递自定义结构体参数(子线程与子线程)

    c++多线程的创建挂起执行与销毁

    4. 新增一个静态的全局变量,用于记录所有线程的状态:static int GlobalVar=10000; 5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID...

    Linux C 多线程编程之互斥锁与条件变量实例详解

    在Linux下, 线程的互斥量数据类型是pthread_mutex_t. 在使用前, 要对它进行初始化: 对于静态分配的互斥量, 可以把它设置为PTHREAD_MUTEX_INITIALIZER, 或者调用pthread_mutex_init. 对于动态分配的互斥量, 在申请...

    CreateThread创建多线程与单线程比较

    第二种是启动多线程,不同模式下启动函数不同,mfc与API与WIN32下面注意点也是有区别的! VC启动一个新线程的三种方法,有需要的朋友可以参考下。 第一种AfxBeginThread() 用AfxBeginThread()函数来创建一个新...

    Linux系统编程之线程同步

    每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。 资源还是共享的,线程间也还是竞争的, 但通过“锁”就将资源的访问变成互斥操作,而后与时间有关的错误也不会再产生了。 但,...

    多线程与智能指针.pdf

    多线程与智能指针 C++线程与智能指针 ⽂章⽬录 线程 线程,有时被称为轻量进程,是程序执⾏的最⼩单元。 C++11线程 #include &lt;thread&gt; void task(int i) { cout ; } thread t1(task,100); //等待线程结束再继续执⾏ ...

    linux系统编程之线程.zip

    线程与共享 线程间共享全局变量! 【牢记】:线程默认共享数据段、代码段等地址空间,常用的是全局变量。而进程不共享全局变量,只能借助mmap。 【练习】:设计程序,验证线程之间共享全局数据。 【glb_var...

    Java多线程大量调用百度地图的搜索功能,来做课程作业数据准备

    判断,自增操作,一开始打算把这个变量的自增操作写成方法,然后用全局锁做互斥,这个时候也把int变量标记为volatile... 之后又改用了AtomicInteger,确实好用多了。每条线程的request请求相互独立,写操作也是相互...

    操作系统读者写者问题源程序

    //全局变量 int readcount=0; //读者数目 int writecount=0; //写者数目 /* 关键代码段是指一个小代码段,在代码能够执行前,它必须独占对某些共享资源的访问权。 这是让若干行代码能够“以原子操作方式”来使用资源...

    c#多线程抓取网页内容

    比如已知用户指定了n(它是一个int型变量)个线程吧,可以用如下方法开启五个线程 Thread[] downloadThread;//声名下载线程,这是C#的优势,即数组初始化时,不需要指定其长度,可以在使用时才指定。这个声名应为类...

    Linux多线程编程(二)

    条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待条件变量的条件成立而挂起(此时不再占用cpu);另一个线程使条件成立(给出条件成立信号)。为了防止竞争,条件变量的使用...

    C++多线程中的锁和条件变量使用教程

    多线程间的状态同步,这个可用的机制很多,条件变量是广泛使用的一种。 今天我用一个简单的例子来给大家介绍下锁和条件变量的使用。 代码使用C++11 示例代码 #include #include #include #include std::mutex ...

    女朋友也能看懂的多线程同步

     当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。  举个案例来说:现在有100张火车票,有两个窗口同时抢火车票,使用多线程模拟抢票效果。 /** * @...

    多线程实现的Java爬虫程序

    以下是一个Java爬虫程序,它能从指定主页开始,按照指定的深度抓取该站点域名下的网页并维护简单索引。  参数:private static int...  本程序用到了多线程(静态变量和同步),泛型,文件操作,URL类和连接,Hashtabl

    Java并发学习-AtomicIntegerFieldUpdater字段原子更新类.docx

    字段的描述类型( 修饰符public/protected/default/private )是与调用者与操作对象字段的关系一致。 也就是说调用者能够直接操作对象字段 ,那么就可以反射进行原子操作。 对于父类的字段,子类是不能直接...

    C++11并发编程关于原子操作atomic的代码示例

    项目中经常用遇到多线程操作共享数据问题,常用的处理方式是对共享数据进行加锁,如果多线程操作共享变量也同样采用这种方式。 为什么要对共享变量加锁或使用原子操作?如两个线程操作同一变量过程中,一个线程执行...

    Golang与python线程详解及简单实例

    Golang与python线程详解及简单实例 在GO中,开启15个线程,每个线程把全局变量遍历增加100000次,因此预测结果是 15*100000=1500000. var sum int var cccc int var m *sync.Mutex func Count1(i int, ch chan int)...

    CoreJava面试题汇总.html

    CoreJava面试题总结。 1 常用的集合有哪些?为什么这么用? 2 静态变量和成员变量的区别 ...8 什么叫线程安全 9 怎么处理异常? 10 int和integer的区别? 11 多态实现的机制 12 wait sleep的区别? 13 start run区别?

    详解Linux多线程编程(不限Linux)

    1)有一int型全局变量g_Flag初始值为0; 2) 在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为1 3) 在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为2 4) 线程序1需要在线程2退出...

    谈谈Java中的i++

    这是和JVM的内存分配有关,JVM在处理这段带代码时,会先把i++的结果赋值给一个临时变量temp,然后再将这个临时变量的值赋值给i。即如下: int i = 0; int temp; // i = i++; int a = temp = i++;// 临时变量...

Global site tag (gtag.js) - Google Analytics