在某些情況下,程序必須等待某個(gè)外部操作執(zhí)行完成,例如輸入操作或輸出操作等,而在等待時(shí)程序無(wú)法執(zhí)行其它任何工作.因此,如果在等待的同時(shí)可以運(yùn)行另一個(gè)程序,那么無(wú)疑提高了資源的利用率.
專注于為中小企業(yè)提供成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)平川免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
不同的用戶和程序?qū)τ?jì)算機(jī)資源有著同等的使用權(quán).一種高效的運(yùn)行方式是通過(guò)粗粒度的時(shí)間片使這些用戶和程序能共享計(jì)算機(jī)資源,而不是一個(gè)程序從頭運(yùn)行到尾,然后在啟動(dòng)下一個(gè)程序.
通常來(lái)說(shuō),在計(jì)算機(jī)多任務(wù)時(shí),應(yīng)該編寫多個(gè)程序,每個(gè)程序執(zhí)行一個(gè)任務(wù)并在必要時(shí)相互通信,這比只編寫一個(gè)程序來(lái)計(jì)算所有的任務(wù)更容易實(shí)現(xiàn).
線程安全性可能是非常復(fù)雜的,在沒有充足的同步情況下,多線程中的執(zhí)行操作順序是不可測(cè)試,會(huì)產(chǎn)生奇怪的問(wèn)題.
如下代碼實(shí)例 : UnsafeSequence.java ,1000個(gè)線程,并發(fā)10次,value++
public class UnsafeSequence { /** 默認(rèn)值0 */ private static int value = 0; /** 線程執(zhí)行數(shù)量 */ private static int threadCount = 1000; /** 并發(fā)數(shù)量 */ private static int concurrentCount = 10; /** 線程池 */ private static ExecutorService executor = Executors.newFixedThreadPool(threadCount); /** 信號(hào)量(并發(fā)數(shù)) */ private static Semaphore semaphore = new Semaphore(concurrentCount); /** 和join方法類似 */ private static CountDownLatch countDownLatch = new CountDownLatch(threadCount); public static int getNext () { return value++; } public static void main (String[] args) { // 啟動(dòng)100 個(gè)線程 并發(fā)10次 去累加 value for (int i = 0; i < threadCount; i++) { executor.execute(() -> { try { // 獲取一個(gè)許可證 semaphore.acquire(); getNext(); // 計(jì)數(shù)器減1 countDownLatch.countDown(); // 歸還一個(gè)許可證 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }); } // 關(guān)閉線程池 executor.shutdown(); try { // 阻塞主線程 直到計(jì)數(shù)器為0 countDownLatch.await(); System.out.println(value); } catch (InterruptedException e) { e.printStackTrace(); } } }
結(jié)果可能是1000或者小于1000,問(wèn)題在于,如果執(zhí)行的時(shí)機(jī)不對(duì),那么兩個(gè)線程在調(diào)用getNext時(shí)會(huì)得到相同的值,雖然遞增運(yùn)算看起來(lái)是單個(gè)操作,但是實(shí)際上是三個(gè)獨(dú)立的操作,讀取value,將value加1,將計(jì)算結(jié)果寫入value,由于多線程交替運(yùn)行,因此兩個(gè)線程同時(shí)執(zhí)行讀操作,讀到了相同的值,結(jié)果寫入主內(nèi)存,結(jié)果就是不同的線程寫入了相同的值.
一個(gè)并發(fā)應(yīng)用程序能及時(shí)執(zhí)行的能力稱為活躍性,常見的有死鎖,饑餓,活鎖問(wèn)題.
性能問(wèn)題包括多個(gè)方面,例如服務(wù)器時(shí)間過(guò)長(zhǎng),響應(yīng)不夠靈敏,吞吐率過(guò)低,資源消耗過(guò)高,或者伸縮性較低等.