JAVA构架之并发编程的一些总结
所謂并發編程是指在一臺處理器上"同時"處理多個任務。并發是在同一實體上的多個事件。多個事件在同一時間間隔發生。
一、程序與進程
程序是一組有序指令的集合,是一種靜態的概念。進程是程序的一次執行,屬于一種動態的概念。在多道程序環境下,程序的執行屬于并發執行,此時它們將失去封閉性,并具有間斷性,運行結果也將不可再現,為了能使多個程序可以并發執行,提高資源利用率和系統吞吐量,并且可以對并發執行的程序加以描述和控制,引入進程的概念。
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>的。
為了讓學習變得輕松、高效,今天給大家免費分享一套Java入門教學資源。幫助大家在成為Java架構師的道路上披荊斬棘。需要資料的歡迎加入學習交流群:9285,05736
總結
以上是生活随笔為你收集整理的JAVA构架之并发编程的一些总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java面向对象多态特性
- 下一篇: 用纸筒做机器人_365天,每天都可以玩出