今天,简洁讲讲如何使用
AtomicBoolean这个类。
类
在java.util.concurrent.atomic包下,有AtomicBoolean , AtomicInteger, AtomicLong, AtomicReference等类,它们的基本特性就是在多线程环境下,执行这些类实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入。
- 介绍:
在这个Boolean值的变化的时候不允许在之间插入,保持操作的原子性
- 方法和举例
- 1.compareAndSet(boolean expect, boolean update)
这个方法主要两个作用 1. 比较AtomicBoolean和expect的值,如果一致,执行方法内的语句。其实就是一个if语句 2. 把AtomicBoolean的值设成update 比较最要的是这两件事是一气呵成的,这连个动作之间不会被打断,任何内部或者外部的语句都不可能在两个动作之间运行。为多线程的控制提供了解决的方案。
这个函数应该是比较常用的,下面讲讲其他的基本使用。
2.构造函数
1.
AtomicBoolean()
使用初始值
false
创建新的AtomicBoolean
。2.
AtomicBoolean(
boolean initialValue
)使用给定的初始值创建新的
AtomicBoolean
。3.方法详解
get
public final boolean get()
-
返回当前值。
-
-
返回:
- 当前值
compareAndSet
public final boolean compareAndSet(boolean expect, boolean update)
-
如果当前值
==
预期值,则以原子方式将该值设置为给定的更新值。 -
-
参数:
-
expect
- 预期值 -
update
- 新值
返回:
- 如果成功,则返回 true。返回 False 指示实际值与预期值不相等。
-
weakCompareAndSet
public boolean weakCompareAndSet(boolean expect, boolean update)
-
如果当前值
==
预期值,则以原子方式将该值设置为给定的更新值。可能意外失败并且不提供排序保证,因此几乎只是
compareAndSet
的适当替代方法。 -
-
参数:
-
expect
- 预期值 -
update
- 新值
返回:
- 如果成功,则返回 true。
-
set
public final void set(boolean newValue)
-
无条件地设置为给定值。
-
-
参数:
-
newValue
- 新值
-
lazySet
public final void lazySet(boolean newValue)
-
最终设置为给定值。
-
-
参数:
-
newValue
- 新值
从以下版本开始:
- 1.6
-
getAndSet
public final boolean getAndSet(boolean newValue)
-
以原子方式设置为给定值,并返回以前的值。
-
-
参数:
-
newValue
- 新值
返回:
- 以前的值
-
toString
public String toString()
下面简单举一个使用的例子。
以AtomicBoolean为例,单线程执行普通的方法(如下),不会出现线程问题:
package com.secbro.test.atomic; /** * @author zhuzhisheng * @Description * @date on 2016/5/26. */ public class NormalBoolean implements Runnable{ public static boolean exits = false; private String name; public NormalBoolean(String name){ this.name = name; } @Override public void run() { if(!exits){ exits = true; System.out.println(name + ",step 1"); System.out.println(name + ",step 2"); System.out.println(name + ",step 3"); exits = false; } else { System.out.println(name + ",step else"); } } public static void main(String[] args) { new NormalBoolean("张三").run(); } }
然而,当多线程执行时,就会出现在执行判断之后的命令时,会有其他线程插入,变更exits的值。如下段代码:
package com.secbro.test.atomic; /** * @author zhuzhisheng * @Description * @date on 2016/5/26. */ public class NormalBoolean2 implements Runnable{ public static boolean exits = false; private String name; public NormalBoolean2(String name) { this.name = name; } @Override public void run() { if(!exits){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } exits = true; System.out.println(name + ",step 1"); System.out.println(name + ",step 2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + ",step 3"); exits = false; } else { System.out.println(name + ",step else"); } } }
同时执行两线程,打印结果为:
张三,step 1 李四,step 1 张三,step 2 李四,step 2 张三,step 3 李四,step 3
现在,使用AtomicBoolean就可以确保多线程的情况下安全的运行,只有一个线程进行业务处理。
package com.secbro.test.atomic; import java.util.concurrent.atomic.AtomicBoolean; /** * @author zhuzhisheng * @Description * @date on 2016/5/26. */ public class TestAtomicBoolean implements Runnable{ public static AtomicBoolean exits = new AtomicBoolean(false); private String name; public TestAtomicBoolean(String name) { this.name = name; } @Override public void run() { if(exits.compareAndSet(false,true)){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + ",step 1"); System.out.println(name + ",step 2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + ",step 3"); exits.set(false); } else { System.out.println(name + ",step else"); } } }
当两个线程执行此类时,打印结果如下:
张三,step else 李四,step 1 李四,step 2 李四,step 3
测试类:
package com.secbro.test.atomic; /** * @author zhuzhisheng * @Description * @date on 2016/5/26. */ public class TestBoolean { public static void main(String[] args) { Thread thread1 = new Thread(new NormalBoolean2("李四")); Thread thread2 = new Thread(new NormalBoolean2("张三")); thread1.start(); thread2.start(); //------------------------------------------------------- Thread thread3 = new Thread(new TestAtomicBoolean("李四")); Thread thread4 = new Thread(new TestAtomicBoolean("张三")); thread3.start(); thread4.start(); } }
这是将网上资料进行了这里,大家可以自己去查找资料看看。其实我也基本没有使用过这个类,但是记录一下。
android AtomicBoolean类的使用就讲完了。
就这么简单。