1. 程式人生 > >java的併發類

java的併發類

java記憶體模型

這裡寫圖片描述

 ①每個執行緒都有一個自己的本地記憶體空間--執行緒棧空間???執行緒執行時,先把變數從主記憶體讀取到執行緒自己的本地記憶體空間,然後再對該變數進行操作

 ②對該變數操作完後,在某個時間再把變數重新整理回主記憶體
  • voaltile 與 synchronized
  voaltile關鍵字,使一個變數在多個執行緒中可見
  A、B執行緒都用到一個變數,java預設是A執行緒中保留一份copy,如果B執行緒修改了這個變數,則A執行緒未必知道
  使用voaltile關鍵字,會讓所有執行緒都會讀到變數得修改值
  舉例:當執行緒t1開始執行得時候,會把count
值從記憶體中讀到t1執行緒得工作區,在執行過程中直接使用這個copy, 不會每次去讀取堆記憶體,這樣當主執行緒修改count值之後,t1執行緒感知不到,所以不會停止執行 但是volatile並不能保證多個執行緒共同修改count變數所帶來得不一致得問題,volatile並不能代替synchonized
  public class T {
      /*volatile*/ boolean running = true
; //對比一下有無volatile的情況下,整個程式執行結果的區別 void m() { System.out.println("m start"); while (running) { /*try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }*/ } System.out.println("m end!"
); } public static void main(String[] args) { T t = new T(); new Thread(t::m, "t1").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } t.running = false; } }
  • synchronized
volatile輕量級,只能修飾變數。synchronized重量級,還可修飾方法

  ②volatile只能保證資料的可見性,不能用來同步,因為多個執行緒併發訪問volatile修飾的變數不會阻塞。

  synchronized不僅保證可見性,而且還保證原子性,因為,只有獲得了鎖的執行緒才能進入臨界區,從而保證臨界區中的所有語句都全部執行。多個執行緒爭搶synchronized鎖物件時,會出現阻塞。

public class T {
    /*volatile*/ int count = 0;

    synchronized void m() { 
        for (int i = 0; i < 10000; i++)
            count++;
    }

    public static void main(String[] args) {
        T t = new T();

        List<Thread> threads = new ArrayList<Thread>();

        for (int i = 0; i < 10; i++) {
            threads.add(new Thread(t::m, "thread-" + i));
        }

        threads.forEach((o) -> o.start());

        threads.forEach((o) -> {
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        System.out.println(t.count);

    }
}
  • reentrantlock 可重入鎖
重入鎖 必須手動釋放鎖 設定公平鎖
  • 佇列
ConcurrentLinkedQueue  非阻塞高併發佇列 
LinkedBlockingQueue 無界佇列 是連結串列實現得阻塞佇列,在連結串列一頭加入元素,如果佇列滿,就會阻塞,另一頭取出元素,如果佇列空,就會等待
ArrayBlockingQueue  有界佇列 比如設定10個佇列 當put進去10個 在put時就會阻塞
TransferQueue      直接交給消費者消費
SynchronusQueue    容量為0  生產了要馬上消費
DelayQueue執行定時任務  在這個任務中的元素預設多長時間被消費者消費
  • 執行緒
http://www.cnblogs.com/zhujiabin/p/5404771.html
newCachedThreadPool 快取的執行緒池 當來了2個任務就啟動2個執行緒  當第三個任務來了時候前面執行緒執行完成後就不在啟動第三個執行緒來執行。當前面的沒
                     有執行完成就啟動第三個執行緒執行
newSingleThreadExecutor 一個執行緒池
newFixedThreadPool 建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。
newScheduledThreadPool 建立一個定長執行緒池,支援定時及週期性任務執行。
ThreadPoolExecutor( int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler)                                                                                                                                                                                                                       
    corePoolSize 核心執行緒池大小
    maximumPoolSize 執行緒池最大容量大小
    keepAliveTime 執行緒池空閒時,執行緒存活的時間
    TimeUnit 時間單位
    ThreadFactory 執行緒工廠
    BlockingQueue任務佇列
    RejectedExecutionHandler 執行緒拒絕策略