類
在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(); } }
然而,當多執行緒執行時,就會出現在執行判斷之後的指令時,會有其他執行緒插入,變更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(); } }
以上是java中Atomic類之AtomicBoolean的詳細內容。更多資訊請關注PHP中文網其他相關文章!