Java Condition

根據工做經驗,總結Java併發的使用 java

public class SingletonData {
    private static final int QUEUE_MAX_SIZE = 500;
    private static Integer[] blockingQueue = new Integer[QUEUE_MAX_SIZE];
    private static int count = 0;
    private static ReentrantLock lock = new ReentrantLock();
    private static int putptr = 0;  //寫索引
    private static int takeptr = 0; //讀索引
    final static Condition notFull = lock.newCondition(); //寫線程鎖
    final static Condition notEmpty = lock.newCondition(); //讀線程鎖

    private SingletonData() {
    }

    ;

    private static class SingletonHolder {
        /**
        * 靜態初始化器,由JVM來保證線程安全
        */
        private static SingletonData queue = new SingletonData();
    }

    public static SingletonData getSingletonData() {
        return SingletonHolder.queue;
    }

    public void set(Integer data) {
        lock.lock();// 取到寫鎖
        try {
            System.out.println(Thread.currentThread().getName() + "準備寫入數據");
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            blockingQueue[putptr] = data;
            if (++putptr == blockingQueue.length) putptr = 0;
            ++count;
            notEmpty.signal();

        } finally {
            lock.unlock();//解除鎖定
        }
    }

    public Integer[] getBlockingQueue() {
        return blockingQueue;
    }

    public int get() {
        lock.lock(); //鎖定
        try {
            // 若是隊列空,則阻塞<讀線程>
            while (count == 0) {
                notEmpty.await();
            }

            //讀取隊列,並更新讀索引
            int x = blockingQueue[takeptr];
            if (++takeptr == blockingQueue.length) takeptr = 0;
            --count;

            // 喚醒<寫線程>
            notFull.signal();
            return x;
        }catch (Exception e){
            return 0;
        } finally {
            lock.unlock();//解除鎖定
        }
    }

}

 

public class CallableDemo {
    public static void main(String[] args){
        ExecutorService executorService = Executors.newFixedThreadPool(40);
        List<Future<String>> resultList = new ArrayList<Future<String>>();

        //建立10個任務並執行
        for (int i = 0; i < 500; i++){
            //使用ExecutorService執行Callable類型的任務,並將結果保存在future變量中
            Future<String> future = executorService.submit(new TaskWithResult(i));
            //將任務執行結果存儲到List中
            resultList.add(future);
        }

        //遍歷任務的結果
        for (Future<String> fs : resultList){
            try{
                while(! fs.isDone());//Future返回若是沒有完成,則一直循環等待,直到Future返回完成
                System.out.println(fs.get());     //打印各個線程(任務)執行的結果
            }catch(InterruptedException e){
                e.printStackTrace();
            }catch(ExecutionException e){
                e.printStackTrace();
            }finally{
                //啓動一次順序關閉,執行之前提交的任務,但不接受新任務
                executorService.shutdown();
            }
        }
        List<Integer> eles =  Arrays.asList( SingletonData.getSingletonData().getBlockingQueue());
        eles.sort((a,b)->{return( a > b? a : b); });

        for(Integer ele : eles){
            System.out.println(ele);
        }

        System.out.println(eles.size());
    }
}


class TaskWithResult implements Callable<String> {
    private int id;

    public TaskWithResult(int id){
        this.id = id;
    }

    /**
     * 任務的具體過程,一旦任務傳給ExecutorService的submit方法,
     * 則該方法自動在一個線程上執行
     */
    @Override
    public String call() throws Exception {
        System.out.println("call()方法被自動調用!!!    " + Thread.currentThread().getName());
        //該返回結果將被Future的get方法獲得
        SingletonData.getSingletonData().set(id);
        return "call()方法被自動調用,任務返回的結果是:" + id + "    " + Thread.currentThread().getName();
    }
}
相關文章
相關標籤/搜索