根據工做經驗,總結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(); } }