`

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关键字

分享到:
评论

相关推荐

    C#多线程互斥实例 多线程获取同一变量

    在这个"多线程互斥实例 多线程获取同一变量"的示例中,我们将探讨如何在多个线程中安全地访问共享资源,避免数据不一致性和竞态条件。 首先,我们需要理解多线程中的一些核心概念: 1. **线程**:线程是操作系统...

    采用全局变量方式实现多线程的通信

    线程A和线程B在访问`g_sharedData`之前都会先获取临界区的锁,确保在任何时候只有一个线程能够操作这个变量。 然而,全局变量并不是多线程通信的理想解决方案,因为它可能导致代码难以理解和维护,以及增加了数据...

    Qt 多线程访问同一个变量

    标题"Qt 多线程访问同一个变量"涉及到的是如何在多线程环境下确保对共享资源(此处为一个全局变量)的安全访问。描述中提到了使用互斥锁来解决这个问题,并通过创建两个线程ThreadA和ThreadB来演示这一过程。 首先...

    c++通过结构体(struct)全局变量在多线程中传递参数

    `workerThread`函数和`main`函数分别在不同的线程中操作`value`,每次修改前都先锁定互斥锁,确保了线程安全。 在Linux环境下,使用`make`编译多线程程序通常需要链接`pthread`库。`Makefile`可能如下所示: ```...

    Java线程安全.docx

    线程操作某个对象时,执行顺序如下:从主存复制变量到当前工作内存、执行代码、改变共享变量值、用工作内存数据刷新主存相关内容。 有序性是指线程在引用变量时不能直接从主内存中引用,如果线程工作内存中没有该...

    Java多线程 - (一) 最简单的线程安全问题

    一个方法或变量被称为线程安全,当它在多线程环境下被调用时,仍然能保证其正确性和完整性。线程不安全则可能引发竞态条件(race condition),即多个线程同时访问和修改同一份数据,导致结果不可预测。 在Java中,...

    线程安全总结.doc

    **静态变量线程不安全测试代码** ```java package com.suning.test.thread.staticV; public class StaticVariableTest extends Thread { private static int static_i = 0; @Override public void run() {...

    使用C++11实现线程安全的单例模式

    线程安全的单例模式实现可以基于静态局部变量和`std::call_once`。以下是一个简单的示例: ```cpp #include class Singleton { private: Singleton() {} // 私有构造函数 static std::once_flag init_flag; ...

    线程安全Vector

    实际上,线程安全性不仅需要满足基本的功能需求,还需要考虑到类的规格说明,即该类的功能、副作用、有效的状态、不变量等。 #### 二、线程安全的Vector详解 ##### Vector概述 `Vector` 是 Java 集合框架中最早...

    Java多线程与线程安全实践-基于Http协议的断点续传.zip

    总的来说,Java多线程与线程安全实践对于理解和实现基于HTTP协议的断点续传功能至关重要。通过合理地运用多线程、同步机制和原子变量,可以构建出高效、安全的并发应用程序。这个实践项目会深入讲解这些概念,并提供...

    Servlet线程安全问题.docx

    Servlet的线程安全问题与多线程环境 在多线程环境下,Servlet的线程安全问题主要体现在实例变量的共享上。对于局部变量,每个线程都有自己的副本,因此它们之间的修改不会相互影响,是线程安全的。然而,Servlet实例...

    Java 多线程 订票 示例 线程安全

    然而,多线程环境下的数据共享和操作可能会引发线程安全问题,如果不正确处理,可能导致数据不一致、程序崩溃等严重后果。本示例将探讨如何在Java中实现一个线程安全的订票系统。 首先,我们要理解什么是线程安全。...

    操作系统多线程的创建

    4. **线程同步与通信**:在多线程环境中,为了防止数据竞争和确保数据一致性,需要使用同步机制,如互斥量(`std::mutex`)、条件变量(`std::condition_variable`)、信号量(`std::semaphore`)等。例如,`std::...

    Java中对AtomicInteger和int值在多线程下递增操作的测试

    这个话题将深入探讨`AtomicInteger`与普通`int`变量在多线程环境下进行递增操作的差异。 `AtomicInteger`是Java `util.concurrent.atomic`包中的一个类,它提供了一种无锁的、线程安全的整数操作方式。在多线程环境...

    Java多线程-线程安全问题练习题

    3. **原子操作类**:如`java.util.concurrent.atomic`包中的类,提供原子性操作,避免了线程安全问题。 4. **线程局部变量**:`ThreadLocal`类,为每个线程提供独立的变量副本,避免了共享状态的问题。 5. **并发...

    Java线程安全.pdf

    在这个例子中,`AtomicInteger`的`addAndGet()`方法就是一个原子操作,它保证了线程a和线程b在操作`balance`时不会出现竞态条件,从而确保了线程安全。 总的来说,理解Java内存模型以及其对可见性和有序性的规定,...

    Java多线程与线程安全实践-基于Http协议的断点续传

    `Atomic`类提供原子操作,确保操作不会被线程中断;`Lock`接口提供了比`synchronized`更细粒度的锁控制。 在基于HTTP协议的断点续传中,我们通常会利用HTTP的Range请求头来实现。Range请求允许客户端指定要获取的...

    Java多线程与线程安全实践-基于Http协议的断点续传.rar

    本实践项目“Java多线程与线程安全实践-基于Http协议的断点续传”聚焦于如何利用Java实现基于Http协议的文件断点续传功能,这在大型文件下载、网络传输优化等方面具有广泛应用。 首先,理解Java多线程的基本概念。...

    java线程安全总结

    3. **使用AtomicInteger**:使用`AtomicInteger`来替代`int`类型的`balance`字段,利用原子操作保证线程安全。 #### 六、结论 Java线程安全是多线程编程的基础,它涉及到内存模型、同步机制等多个方面。正确理解和...

Global site tag (gtag.js) - Google Analytics