問題:java
1 如何構造,常用哪些api?api
2 怎麼實現的原子操做?多線程
3 示例demo函數
static { try {//1 使用反射得到成員變量"value" // 2 獲得"value"在內存中的偏移量, 直接操做內存空間,實現對字段value的操做 valueOffset = unsafe.objectFieldOffset (AtomicBoolean.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } /* 實現AtomicBoolean兩個條件: 1 一旦更新,全部的線程讀取最新的值 2 多線程同步更新 */ private volatile int value; //3 volatile使其餘線程可見(知足第一個條件) public AtomicBoolean(boolean initialValue) { value = initialValue ? 1 : 0; //4 value的值,要麼是1(true),要麼是0(false) } public AtomicBoolean() { // 默認是false } public final boolean compareAndSet(boolean expect, boolean update) { //5 把比較和賦值 一塊兒組合也爲原子操做,返回boolean int e = expect ? 1 : 0; int u = update ? 1 : 0; // 6 CAS多線程同步更新。這是個阻塞函數,線程會不斷嘗試執行,直至成功 return unsafe.compareAndSwapInt(this, valueOffset, e, u); } public final void set(boolean newValue) { value = newValue ? 1 : 0; // }
示例demo:this
public class BarWorker implements Runnable { private static AtomicBoolean exists = new AtomicBoolean(false); private String name; public BarWorker(String name) { this.name = name; } public void run() { // 只容許一個線程去執行,其他線程不執行 if (exists.compareAndSet(false, true)) { System.out.println(name + " enter"); try { System.out.println(name + " working"); TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { // do nothing } System.out.println(name + " leave"); exists.set(false);//設置爲false, 另一個線程開始執行 } else { System.out.println(name + " give up"); } } }
若是我不使用AtomicBoolean,實現一樣的功能,會怎麼作?線程
public class BarWorker2 implements Runnable { private static volatile boolean exists = false;//volatile 使變量可視 private String name; public BarWorker2(String name) { this.name = name; } public void run() { // 只容許一個線程去執行,其他線程不執行 if (exists == false) { // 這幾行組合在一塊兒相似CAS synchronized (BarWorker2.class) { if (exists == false) { exists = true; System.out.println(name + " enter"); try { System.out.println(name + " working"); TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { // do nothing } System.out.println(name + " leave"); } else { System.out.println(name + " give up --- 1"); } } } else { System.out.println(name + " give up --- 2"); } } }