您的位置:首页 > 编程语言 > Java开发

Java基础之线程安全基本数据类型

2017-03-14 17:27 381 查看
先来个美女镇楼!别举报我开车哦~~



我们在开发安卓或者后台的时候,经常会开启多个线程或者进程。这样做的猿友肯定遇见过一个麻烦,那就是有的时候可能会出现多个线程访问一个变量。这个时候可能出现线程错位,访问到了我们不想让那个线程得到的数据。那么怎么办呢,常用的方法就是加锁,使用synchronized(object)加锁,也就是只允许当前一个线程去访问。

byte[]lock =new byte[0];
synchronized(lock){
int i = 0;
system.out.println("test",i++);
}


相信大多数朋友都是这样做的,这里我把锁用空的字节数组,有节省内存的用途。虽然很少,不过节约是一种美德嘛。这些大家都用过,我就不比比了。但是如果在某个函数忘记加锁了,那这就是个隐藏的漏洞。会扣工资的,怎么办呢。sun公司的工程师早就为我们做好了准备。在java1.5加入了Atomic这个帮助类型。在java.util.concurrent.atomic。这里的atomic是线程安全的基本数据类型。去sun官网下载最新api文档就能看到。这里我给大家简单介绍一下Atomic系列的数据类型。先看看sun对atomic包的简介:

A small toolkit of classes that support lock-free thread-safe programming on single variables

大概意思是支持单个变量线程安全编程的一个小工具箱。atomic系列包含以下数据类型。

AtomicBoolean
AtomicInteger
AtomicIntegerArray
AtomicIntegerFieldUpdater
AtomicLong
AtomicLongArray
AtomicLongFieldUpdater
AtomicMarkableReference
AtomicReference
AtomicReferenceArray
AtomicReferenceFieldUpdater
AtomicStampedReference
DoubleAccumulator
DoubleAdder
LongAccumulator
LongAdder


我就拿常用的Integer和Boolean来讲解,其他的参照着使用就ok了。

AtomicBoolean

public class AtomicBoolean extends Object implements Serializable


构造函数

AtomicBoolean() 创建一个新的 AtomicBoolean 初始化为默认 false.

AtomicBoolean(boolean initialValue) 创建一个新的 AtomicBoolean使用参数进行初始化.

具体方法

boolean compareAndSet(boolean expect, boolean update)

先进行判断,如果当前atomicboolean的value == expect,那么就会自动设置当前atomicboolean的value=update。返回值是expect和value的比较。

boolean get() 返回当前对象的boolean值

boolean getAndSet(boolean newValue) 先返回当前对象的value,在设置新的值给当前对象。

void set(boolean newValue) 设置当前对象的值

boolean weakCompareAndSet(boolean expect, boolean update) 先进行判断,如果当前atomicboolean的value == expect,那么就会自动设置当前atomicboolean的value=update。返回值是expect和value的比较。

AtomicInteger

public class AtomicInteger extends Number implements Serializable


构造函数

AtomicInteger() 创建一个新的 AtomicBoolean 初始化为默认 0.

AtomicInteger(int initialValue)创建一个新的 AtomicInteger使用参数进行初始化.

具体方法

int addAndGet(int delta) 先加上delta,在返回当前对象值,有点像++i

boolean compareAndSet(int expect, int update) 先比较当前value == expect,如果是true,则自动更新当前value为update。返回value == expect的值

int decrementAndGet() 自减1,返回结果

double doubleValue() 当前值转换为double并返回

float floatValue() 当前值转换为float 并返回

int get() 获取当前对象值

int getAndAdd(int delta) 先获得当前值,再加上delta赋给当前对象

int getAndDecrement() 先获得当前值,再自动减1

int getAndIncrement() 先获得当前值,再自动加1

int getAndSet(int newValue) 先获取当前值,在设置当前值为newValue

int incrementAndGet() 自加1,然后在返回当前值

int intValue() 返回当前int基本数据类型值,包装类对应的基本数据类型

void set(int newValue) 设置当前值

具体使用

import java.util.concurrent.atomic.AtomicInteger;

public class TestAtomic {

public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(1);

int number = 0;

//getAndAdd: 先获取值,再自增10,返回值为自增前的值
number = atomicInteger.getAndAdd(10);
System.out.println("getAndAdd       --> number:" + number + ", atomicInteger: " + atomicInteger);

//getAndDecrement: 先获得值,再自减1,返回值为自减前的
number = atomicInteger.getAndDecrement();
System.out.println("getAndDecrement --> number:" + number + ", atomicInteger: " + atomicInteger);

//getAndIncrement: 先获得值,再自增1,返回值为自增前的值
number = atomicInteger.getAndIncrement();
System.out.println("getAndIncrement --> number:" + number + ", atomicInteger: " + atomicInteger);

//getAndSet: 先获得值,再赋值,返回值为赋值前的值
number = atomicInteger.getAndSet(10);
System.out.println("getAndSet       --> number:" + number + ", atomicInteger: " + atomicInteger);

//addAndGet: 先自增,再返回值,返回值为自增后的值
number = atomicInteger.addAndGet(10);
System.out.println("addAndGet       --> number:" + number + ", atomicInteger: " + atomicInteger);

//decrementAndGet: 先自减1,再获取返回值,返回值为自减后的值
number = atomicInteger.decrementAndGet();
System.out.println("decrementAndGet --> number:" + number + ", atomicInteger: " + atomicInteger);

//incrementAndGet: 先自增1,再返回值,返回值为自增后的值
number = atomicInteger.incrementAndGet();
System.out.println("incrementAndGet --> number:" + number + ", atomicInteger: " + atomicInteger);

//compareAndSet: 如果当前值为20,则设置为100
boolean isSuccess = atomicInteger.compareAndSet(20, 100);
System.out.println("compareAndSet: " + isSuccess);

}
}


getAndAdd       --> number:1, atomicInteger: 11
getAndDecrement --> number:11, atomicInteger: 10
getAndIncrement --> number:10, atomicInteger: 11
getAndSet       --> number:11, atomicInteger: 10
addAndGet       --> number:20, atomicInteger: 20
decrementAndGet --> number:19, atomicInteger: 19
incrementAndGet --> number:20, atomicInteger: 20
compareAndSet: true


简单使用就是这样,为了避免线程错误,在可能多线程访问数据的情况下,建议使用atomic工具包的基本数据类。其他的类的使用大同小异,简单看看就会了。

觉得有用请点个赞,谢谢。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息