一些小细节
应用启动初始化的时候有时候会判定下是否已经初始化过了。这个时候会设置一个变量,然后判断,然后设值。如果有概率发生并发的初始化,有可能还要加个锁。非常不简洁。下面这个方式,就让这个检查并设值的原子操作给底下来做吧,比较简洁。
if(!startFlag.compareAndSet(false, true)){return;}public class CyclicBarrierTest { public static void main(String[] args){ final CyclicBarrier cb=new CyclicBarrier(10, new Runnable() {@Overridepublic void run() {System.out.println("get here!");}}); for(int i=0;i<100;i++){ final int index=i; Thread t=new Thread(new Runnable() {@Overridepublic void run() {System.out.println("i am "+index);try {cb.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}); t.start(); } }}i am 0i am 9i am 7i am 5i am 3i am 1i am 13i am 11i am 4i am 2get here!i am 6i am 10i am 15i am 8i am 14i am 12i am 17i am 16i am 18i am 20get here!i am 22i am 24i am 26i am 28i am 30i am 19i am 21i am 23i am 32i am 25get here!i am 34i am 36i am 38i am 29i am 31i am 35i am 37i am 27i am 33i am 39i am 50get here!...
/** * Compiled Expression cache */ private final static ConcurrentHashMap<String/* text expression */, FutureTask<Expression>/* * Compiled * expression * task */> cacheExpressions = new ConcurrentHashMap<String, FutureTask<Expression>>(); /** * Compile a text expression to Expression object * * @param expression * text expression * @param cached * Whether to cache the compiled result,make true to cache it. * @return */ public static Expression compile(final String expression, boolean cached) { if (expression == null || expression.trim().length() == 0) { throw new CompileExpressionErrorException("Blank expression"); } if (cached) { FutureTask<Expression> task = cacheExpressions.get(expression); if (task != null) { return getCompiledExpression(expression, task); } task = new FutureTask<Expression>(new Callable<Expression>() { public Expression call() throws Exception { return innerCompile(expression); } }); FutureTask<Expression> existedTask = cacheExpressions.putIfAbsent(expression, task); if (existedTask == null) { existedTask = task; existedTask.run(); } return getCompiledExpression(expression, existedTask); } else { return innerCompile(expression); } } private static Expression getCompiledExpression(final String expression, FutureTask<Expression> task) { try { return task.get(); } catch (Exception e) { cacheExpressions.remove(expression); throw new CompileExpressionErrorException("Compile expression failure:" + expression, e); } }private static Integer allocateId(Channel channel) { Integer id = Integer.valueOf(System.identityHashCode(channel)); for (;;) { // Loop until a unique ID is acquired. // It should be found in one loop practically. if (allChannels.putIfAbsent(id, channel) == null) { // Successfully acquired. return id; } else { // Taken by other channel at almost the same moment. id = Integer.valueOf(id.intValue() + 1); } } }