log.error(ex);
System.err.println(ex);
    public void testConcurrentAccess() {        final int NUM_THREADS=10;        final int INTERVAL=20000;        Writer[] writers=new Writer[NUM_THREADS];        Reader[] readers=new Reader[NUM_THREADS];        int[] writes=new int[NUM_THREADS];        int[] reads=new int[NUM_THREADS];        long total_reads=0, total_writes=0;        for(int i=0; i < writers.length; i++) {            readers[i]=new Reader(i, reads);            readers[i].start();            writers[i]=new Writer(i, writes);            writers[i].start();        }        Util.sleep(INTERVAL);        System.out.println("current queue size=" + queue.size());        for(int i=0; i < writers.length; i++) {            writers[i].stopThread();        }        for(int i=0; i < readers.length; i++) {            readers[i].stopThread();        }        queue.close(false); // will cause all threads still blocking on peek() to return        System.out.println("current queue size=" + queue.size());        for(int i=0; i < writers.length; i++) {            try {                writers[i].join(300);                readers[i].join(300);            }            catch(Exception ex) {                log.error(ex);            }        }        for(int i=0; i < writes.length; i++) {            System.out.println("Thread #" + i + ": " + writes[i] + " writes, " + reads[i] + " reads");            total_writes+=writes[i];            total_reads+=reads[i];        }        System.out.println("total writes=" + total_writes + ", total_reads=" + total_reads +                ", diff=" + Math.abs(total_writes - total_reads));    }