【Java】Java併發編程

併發和並行

  • 什麼是併發
    併發是指兩個或多個事件在同一時間間隔發生,但是實際上處理的只能是其中的一個,但是可以交替去處理其他的。

  • 什麼是並行
    兩個或多個事件在同一時刻發生被處理。

  • 併發和並行區別
    一個是交替執行,一個是同時執行.

什麼是線程,與進程的區別

@TODO

線程池

submit() 和 execute()

區別

  • 參數不同
    submit和execute由於參數不同有四種實現形式
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
void execute(Runnable command);
  • submit有返回值,execute沒有
    submit在執行過程中不會拋出異常,而是把異常保存在成員變量中,在Future.get()阻塞獲取到異常信息。
    execute直接拋出異常之後線程就結束了,submit保存異常線程沒有結束。

爲什麼不允許使用 Executors 創建線程池

線程池不允許使用 Executors 去創建,而是通過 ThreadPoolExecutor 的方式。

Executors 返回的線程池對象的弊端
FixedThreadPool 和 SingleThreadPool:允許的請求隊列長度爲 Integer.MAX_VALUE,可能會堆積大量的請求,從而導致 OOM。
CachedThreadPool 和 ScheduledThreadPool:允許的創建線程數量爲 Integer.MAX_VALUE, 可能會創建大量的線程,從而導致 OOM。
Positive example 1//org.apache.commons.lang3.concurrent.BasicThreadFactory
    ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
       
            
Positive example 2:
    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
        .setNameFormat("demo-pool-%d").build();
 
    //Common Thread Pool
    ExecutorService pool = new ThreadPoolExecutor(5, 200,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
 
    pool.execute(()-> System.out.println(Thread.currentThread().getName()));
    pool.shutdown();//gracefully shutdown
           
            
Positive example 3<bean id="userThreadPool"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="10" />
        <property name="maxPoolSize" value="100" />
        <property name="queueCapacity" value="2000" />
 
    <property name="threadFactory" value= threadFactory />
        <property name="rejectedExecutionHandler">
            <ref local="rejectedExecutionHandler" />
        </property>
    </bean>
    //in code
    userThreadPool.execute(thread);

線程安全

線程安全和內存模型的關係

  • 內存模型
    Java內存模型(JMM)包含:工作內存(本地內存)和主內存

工作內存:工作內存可以簡單理解爲計算機當中的CPU高速緩存,但又不完全等同。每一個線程擁有自己的工作內存,對於一個共享變量來說,工作內存當中存儲了它的“副本”。
主內存:主內存可以簡單理解爲計算機當中的內存,但又不完全等同。主內存被所有的線程所共享,對於一個共享變量(比如靜態變量,或是堆內存中的實例)來說,主內存當中存儲了它的“本尊”。
JMM

  • volatile
  1. volatile關鍵字具有許多特性,其中最重要的特性就是保證了用volatile修飾的變量對所有線程的可見性。當一個線程修改了變量的值,新的值會立刻同步到主內存當中。而其他線程讀取這個變量的時候,也會從主內存中拉取最新的變量值。爲什麼volatile關鍵字可以有這樣的特性?這得益於java語言的先行發生原則(happens-before)
  2. 阻止編譯時和運行時的指令重排。編譯時JVM編譯器遵循內存屏障的約束,運行時依靠CPU屏障指令來阻止重排。

鎖的類型

悲觀鎖和樂觀鎖

悲觀鎖

悲觀鎖是就是悲觀思想,即認爲寫多,遇到併發寫的可能性高,每次去拿數據的時候都認爲別人會修改,所以每次在讀寫數據的時候都會上鎖,這樣別人想讀寫這個數據就會block直到拿到鎖。Java中的悲觀鎖就是Synchronized, AQS框架下的鎖則是先嚐試cas樂觀鎖去獲取鎖,獲取不到,纔會轉換爲悲觀鎖,如RetreenLock。

樂觀鎖

樂觀鎖是一種樂觀思想,即認爲讀多寫少,遇到併發寫的可能性低,每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,採取在寫時先讀出當前版本號,然後加鎖操作(比較跟上一次的版本號,如果一樣則更新),如果失敗則要重複讀-比較-寫的操作。
Java中的樂觀鎖基本都是通過CAS操作實現的,CAS(Compare And
Swap)是一種更新的原子操作,比較當前值跟傳入值是否一樣,一樣則更新,否則失敗。

關於鎖的詳細介紹:Java中的偏向鎖、輕量級鎖與重量級鎖(synchronized)

死鎖

synchronized

volatile

sleep 和 wait

wait 和 notify

notify 和 notifyAll

ThreadLocal

用於線程間的數據隔離,爲每一個使用該變量的線程提供一個副本,每個線程都可以獨立的改變自己的副本,而不會和其他的副本衝突。

ThreadLocal類中維護一個Map,用於存儲每一個線程的變量副本,Map中元素的鍵爲線程對象,而值爲對應線程的變量副本。
ThreadLocal在Spring中發揮着巨大的作用,在管理Request作用域中的Bean、事務管理、任務調度、AOP等模塊都出現了它的身影。
Spring中絕大部分Bean都可以聲明成Singleton作用域,採用ThreadLocal進行封裝,因此有狀態的Bean就能夠以singleton的方式在多線程中正常工作了。

ThreadLocal使用場合主要解決多線程中數據數據因併發產生不一致問題。ThreadLocal爲每個線程的中併發訪問的數據提供一個副本,通過訪問副本來運行業務,這樣的結果是耗費了內存,單大大減少了線程同步所帶來性能消耗,也減少了線程併發控制的複雜度。

ThreadLocal不能使用原子類型,只能使用Object類型。ThreadLocal的使用比synchronized要簡單得多。

ThreadLocal和Synchonized都用於解決多線程併發訪問。但是ThreadLocal與synchronized有本質的區別。synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal爲每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的並不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用於在多個線程間通信時能夠獲得數據共享。

Synchronized用於線程間的數據共享,而ThreadLocal則用於線程間的數據隔離。

當然ThreadLocal並不能替代synchronized,它們處理不同的問題域。Synchronized用於實現同步機制,比ThreadLocal更加複雜。

參考鏈接:深入研究java.lang.ThreadLocal類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章