问题: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"); } } }