java中Atomic类之AtomicBoolean

来源:互联网 发布:linux创建目录步骤 编辑:程序博客网 时间:2024/06/05 16:17

目录(?)[-]

  1. 举例说明

在java.util.concurrent.atomic包下,有AtomicBoolean , AtomicInteger, AtomicLong, AtomicReference等类,它们的基本特性就是在多线程环境下,执行这些类实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入。

举例说明

以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();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

然而,当多线程执行时,就会出现在执行判断之后的命令时,会有其他线程插入,变更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");        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

同时执行两线程,打印结果为:

张三,step 1李四,step 1张三,step 2李四,step 2张三,step 3李四,step 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

现在,使用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");        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

当两个线程执行此类时,打印结果如下:

张三,step else李四,step 1李四,step 2李四,step 3
  • 1
  • 2
  • 3
  • 4

测试类:

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();    }}

原创粉丝点击