JAVA技術架構-併發編程學習總結

編程語言 Java CPU 技術 java特種兵 java特種兵 2017-09-14

概述

所謂併發編程是指在一臺處理器上"同時"處理多個任務。併發是在同一實體上的多個事件。多個事件在同一時間間隔發生。

、程序與進程

程序是一組有序指令的集合,是一種靜態的概念。進程是程序的一次執行,屬於一種動態的概念。在多道程序環境下,程序的執行屬於併發執行,此時它們將失去封閉性,並具有間斷性,運行結果也將不可再現,為了能使多個程序可以併發執行,提高資源利用率和系統吞吐量,並且可以對併發執行的程序加以描述和控制,引入進程的概念。

1丶進程和線程

我們知道,為了能使程序能夠併發執行,系統必須進行創建進程、撤銷進程以及進程切換等操作,而進程作為一個資源的擁有者,在進行這些操作時必須為之付出較大的時空開銷。

線程和進程的區別主要如下:(1) 進程是系統中擁有資源的一個基本單位,線程本身並不擁有系統資源,同一進程內的線程共享進程擁有的資源。(2) 進程僅是資源分配的基本單位,線程是調度和分派的基本單位。(3) 線程的併發性更高,可以啟動多個線程執行同程序的不同部分。

2丶並行和併發

並行是指兩個或多個線程在 同一時刻 執行,併發是指兩個或多個線程在 同一時間間隔 內發生。如果程序同時開啟的線程數小於CPU的核數,那麼不同進程的線程就可以分配給不同的CPU來運行,這就是並行,如果線程數多於CPU的核數,那就需要併發技術。

二、Java多線程

開啟的新線程都有一個線程優先級,代表該線程的重要程度,可以通過Thread類的getPriority()和setPriority()來得到或者設置線程的優先級。線程的優先級範圍是1~10,默認情況下是5。

在線程創建完成還未啟動的時候,我們可以通過方法setDaemon()來將線程設置為守護線程。守護線程,簡單理解為後臺運行線程,比如當程序運行時播放背景音樂。守護線程與普通線程在寫法上基本沒有區別,需要注意的是,當進程中所有非守護線程已經結束或者退出的時候,即使還有守護線程在運行,進程仍然將結束。

終止線程?

1、線程自己在run()方法執行完後自動終止

2、調用Thread.stop()方法強迫停止一個線程,不過此方法是不安全的,已經不再建議使用。

3、比較安全可靠的是利用Java的中斷機制,使用方法Thread.interrupt()。需要注意的是,通過中斷並不能直接終止另一個線程,需要被中斷的線程自己處理中斷。被終止的線程一定要添加代碼對isInterrupted狀態進行處理,否則即使代碼是死循環的情況下,線程也將永遠不會結束。

三、線程安全

線程安全性不是一個非真即假的命題。 Vector 的方法都是同步的,並且 Vector 明確地設計為在多線程環境中工作。但是它的線程安全性是有限制的,即在某些方法之間有狀態依賴(類似地,如果在迭代過程中 Vector 被其他線程修改,那麼由 Vector.iterator() 返回的 iterator會拋出ConcurrentModifiicationException)。

這類的規格說明所規定的約束在對象被多個線程訪問時仍然有效,不管運行時環境如何排線程都不需要任何額外的同步。這種線程安全性保證是很嚴格的 -- 許多類,如 Hashtable 或者 Vector 都不能滿足這種嚴格的定義。

四、線程池

在面向對象編程中,創建和銷燬對象是很費時間的,因為創建一個對象要獲取內存資源或者其它更多資源。在Java中更是如此,JVM將試圖跟蹤每個對象,以便能夠在對象銷燬後進行垃圾回收。Java線程池實現了一個Java高併發的、多線程的、可管理的統一調度器,減少創建和銷燬線程對象的次數。

下面詳細介紹一下Java裡的線程池技術,首先看一個類Executors,它是線程的工廠類,方便快速地創建很多線程池。配置一個線程池是比較複雜的,尤其是對於線程池的原理不是很清楚地情況下,很有可能配置的線程池不是最優的,因此在Executors類裡提供了一些靜態工廠,生成一些常用的線程池,常用的方法有:

  • newSingleThreadExecutor()

創建一個單線程的線程池,這個線程池只有一個線程在工作,也就是相當於單線程串行執行所有任務。如果這個唯一的線程因為異常結束,那麼會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行。

  • newFixedThreadExecutor()

傳入參數nThreads,創建一個可重用固定線程數的線程池,以共享的無界隊列方式來運行這些線程。在任意點,最多nThreads個線程會處於處理任務的活動狀態。如果在所有線程處於活動狀態時提交附加任務,則在有可用線程之前,附加任務將在隊列中等待。如果在關閉前的執行期間由於失敗而導致任何線程終止,那麼一個新線程將代替它執行後續的任務。在某個線程被顯示地關閉之前,池中的線程將一直存在。

我們查看newFixedThreadExecutor()的實現,可以看到它裡面就是實例化了一個ThreadPoolExecutor,ThreadPoolExecutor的構造函數如下:

public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);

從上面代碼可以看到幾個參數,corePoolSize表示線程池中線程的穩定峰值,maximumPoolSize表示最大處理線程數,workQueue表示線程等待池,另外在線程池中執行的線程列表是存放在workers中的,它的類型是HashSet<Worker>的。

六、總結

到這裡,關於併發編程的總結就結束了,不足之處還望大家多多包涵!!希望大家可以瞭解什麼是併發編程學習

總結。覺得收穫的話可以點個關注收藏轉發一波喔,謝謝大佬們支持。(吹一波,233~~)

JAVA技術架構-併發編程學習總結

相關推薦

推薦中...