關于Java并發的常用類回顧

volatile 關鍵字

  • 變量聲明為volatile,表示這個變量是不穩定的,每次使用都去主存中讀取

  • Volatile 修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值

  • 問題:兩個線程分別讀寫volatile變量,線程A寫入變量,線程B讀取的時候會看到寫入volatile變量之前所有可見的共享變量

  • Volatile一般情況下不能代替sychronized,因為volatile不能保證操作的原子性,即使只是i++,實際上也是由多個原子操作組成

  • volatile關鍵字用于聲明簡單類型變量,如int、float、 boolean等數據類型。如果這些簡單數據類型聲明為volatile,對它們的操作就會變成原子級別的。但這有一定的限制:

    • 當變量的值由自身的上一個決定時,如n=n+1、n++ 等,volatile關鍵字將失效
    • 只有當變量的值和自身上一個值無關時對該變量的操作才是原子級別的,如n = m + 1,這個就是原子級別的

synchronizedList

  • 包裹了普通的ArrayList提供了線程安全的機制,類似Vector,所以到此為止synchronizedList與Vector的區別就是ArrayList與Vector的增量速度區別,所以需要線程安全操作時,增量比較快的時候推薦使用Vector
  • synchronizedList在迭代的時候,需要開發者自己加上線程鎖控制代碼
  • 因為迭代器涉及的代碼沒有在java api中沒有加上線程同步代碼

Executor框架

  • Executor 框架包括:線程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable 等。

  • 分類

    • Executors.newCachedThreadPool();
    • Executors.newFixedThreadPool(5);
    • Executors.newSingleThreadExecutor();
    • Executors.newScheduledThreadPool(3);
  • Callble任務

    • Callable 中的 call()方法類似 Runnable 的 run()方法,區別同樣是有返回值,后者沒有
    • Future.get()得到返回結果
  • 自定義線程池,可以用 ThreadPoolExecutor 類創建

      public ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long         keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue)
    
  • 當有新的任務要處理時,先看線程池中的線程數量是否大于 corePoolSize,再看緩沖隊列 workQueue 是否滿,最后看線程池中的線程數量是否大于 maximumPoolSize。

Lock鎖

  • Lock 接口有 3 個實現它的類:
    • ReentrantLock
    • ReetrantReadWriteLock.ReadLock
    • ReetrantReadWriteLock.WriteLock
  • Java 5 中引入了注入 AutomicInteger、AutomicLong、AutomicReference 等特殊的原子性變量類,它們提供的如:compareAndSet()、incrementAndSet()和getAndIncrement()等方法都使用了 CAS 操作
  • 條件變量Condition實現線程間協作
    • await()、signal()、signalAll()

阻塞隊列

  • 阻塞隊列的接口是 java.util.concurrent.BlockingQueue,它有多個實現類:ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue 等

  • ArrayBlockingQueue :一個由數組結構組成的有界阻塞隊列。

    • 默認情況下不保證訪問者公平的訪問隊列,概念:先阻塞的消費者線程,可以先從隊列里獲取元素
  • LinkedBlockingQueue :一個由鏈表結構組成的有界阻塞隊列。

  • PriorityBlockingQueue :一個支持優先級排序的無界阻塞隊列。

    • 默認情況下元素采取自然順序排列,也可以通過比較器comparator來指定元素的排序規則
  • DelayQueue:一個使用優先級隊列實現的無界阻塞隊列。

    • 隊列中的元素必須實現Delayed接口,在創建元素時可以指定多久才能從隊列中獲取當前元素。只有在延遲期滿時才能從隊列中提取元素
  • SynchronousQueue:一個不存儲元素的阻塞隊列。

    • 每一個put操作必須等待一個take操作
  • LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。

  • LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。

    • 相比其他的阻塞隊列,LinkedBlockingDeque多了addFirst,addLast,offerFirst,offerLast,peekFirst,peekLast等方法

阻塞棧

  • 阻塞棧的接口java.util.concurrent.BlockingDeque
  • 多種實現

并發新特性—障礙器 CyclicBarrier

  • 創建一組任務,它們并發地執行工作,指定一個任務,該組任務全部執行結束,這個任務才得以執行

信號量Semaphore

  • 可以通過使用信號量來自定義實現類似 Java 中的 synchronized、wait、notify 機制。
  • 以控制某個資源被同時訪問的任務數,它通過acquire()獲取一個許可,release()釋放一個許可。如果被同時訪問的任務數已滿,則其他 acquire 的任務進入等待狀態,直到有一個任務被 release 掉,它才能得到許可。
  • 注意是對并發訪問的任務數進行監控,而不會保證線程安全

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • layout: posttitle: 《Java并發編程的藝術》筆記categories: Javaexcerpt...
    xiaogmail閱讀 5,864評論 1 19
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,366評論 11 349
  • 一.線程安全性 線程安全是建立在對于對象狀態訪問操作進行管理,特別是對共享的與可變的狀態的訪問 解釋下上面的話: ...
    黃大大吃不胖閱讀 865評論 0 3
  • You are given two non-empty linked lists representing two...
    matrxyz閱讀 148評論 0 0
  • 1、 我是個抑郁癥患者,在人多的地方,我時常感到痛苦,獨處是我最快樂的時光。我白天和同學一起讀書、吃飯、玩耍,夜里...
    會紅的眼閱讀 828評論 24 49