1. 程式人生 > >java 高併發面試題

java 高併發面試題

版權宣告:本文為博主原創文章,未經博主允許不得轉載。    https://blog.csdn.net/u012998254/article/details/79400549 1、執行緒與程序 程序是一個實體。每一個程序都有它自己的地址空間,一般情況下,包括文字區域(text region)、資料區域(data region)和堆疊(stack region)。文字區域儲存處理器執行的程式碼;資料區域儲存變數和程序執行期間使用的動態分配的記憶體;堆疊區域儲存著活動過程呼叫的指令和本地變數。 一個標準的執行緒由執行緒ID,當前指令指標(PC),暫存器集合和堆疊組成。另外,執行緒是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。 區別不同  a,地址空間:程序內的一個執行單元;程序至少有一個執行緒;它們共享程序的地址空間;而程序有自己獨立的地址空間;  b,資源擁有:程序是資源分配和擁有的單位,同一個程序內的執行緒共享程序的資  c,執行緒是處理器排程的基本單位,但程序不是.  d,二者均可併發執行. 2、 守護執行緒 在Java中有兩類執行緒:使用者執行緒 (User Thread)、守護執行緒 (Daemon Thread)。  守護執行緒和使用者執行緒的區別在於:守護執行緒依賴於建立它的執行緒,而使用者執行緒則不依賴。舉個簡單的例子:如果在main執行緒中建立了一個守護執行緒,當main方法執行完畢之後,守護執行緒也會隨著消亡。而使用者執行緒則不會,使用者執行緒會一直執行直到其執行完畢。在JVM中,像垃圾收集器執行緒就是守護執行緒。

3、java thread狀態 NEW 狀態是指執行緒剛建立, 尚未啟動 RUNNABLE 狀態是執行緒正在正常執行中, 當然可能會有某種耗時計算/IO等待的操作/CPU時間片切換等, 這個狀態下發生的等待一般是其他系統資源, 而不是鎖, Sleep等 BLOCKED 這個狀態下, 是在多個執行緒有同步操作的場景, 比如正在等待另一個執行緒的synchronized 塊的執行釋放, 也就是這裡是執行緒在等待進入臨界區 WAITING 這個狀態下是指執行緒擁有了某個鎖之後, 呼叫了他的wait方法, 等待其他執行緒/鎖擁有者呼叫 notify / notifyAll 一遍該執行緒可以繼續下一步操作, 這裡要區分 BLOCKED 和 WATING 的區別, 一個是在臨界點外面等待進入, 一個是在理解點裡面wait等待別人notify, 執行緒呼叫了join方法 join了另外的執行緒的時候, 也會進入WAITING狀態, 等待被他join的執行緒執行結束 TIMED_WAITING 這個狀態就是有限的(時間限制)的WAITING, 一般出現在呼叫wait(long), join(long)等情況下, 另外一個執行緒sleep後, 也會進入TIMED_WAITING狀態 TERMINATED 這個狀態下表示 該執行緒的run方法已經執行完畢了, 基本上就等於死亡了(當時如果執行緒被持久持有, 可能不會被回收) 4、請說出與執行緒同步以及執行緒排程相關的方法。 wait():使一個執行緒處於等待(阻塞)狀態,並且釋放所持有的物件的鎖; sleep():使一個正在執行的執行緒處於睡眠狀態,是一個靜態方法,呼叫此方法要處理InterruptedException異常; notify():喚醒一個處於等待狀態的執行緒,當然在呼叫此方法的時候,並不能確切的喚醒某一個等待狀態的執行緒,而是由JVM確定喚醒哪個執行緒,而且與優先順序無關; notityAll():喚醒所有處於等待狀態的執行緒,該方法並不是將物件的鎖給所有執行緒,而是讓它們競爭,只有獲得鎖的執行緒才能進入就緒狀態; 5、程序排程演算法 實時系統:FIFO(First Input First Output,先進先出演算法),SJF(Shortest Job First,最短作業優先演算法),SRTF(Shortest Remaining Time First,最短剩餘時間優先演算法)。  互動式系統:RR(Round Robin,時間片輪轉演算法),HPF(Highest Priority First,最高優先順序演算法),多級佇列,最短程序優先,保證排程,彩票排程,公平分享排程。

6、wait()和sleep()的區別 sleep來自Thread類,和wait來自Object類 呼叫sleep()方法的過程中,執行緒不會釋放物件鎖。而 呼叫 wait 方法執行緒會釋放物件鎖 sleep睡眠後不出讓系統資源,wait讓出系統資源其他執行緒可以佔用CPU sleep(milliseconds)需要指定一個睡眠時間,時間一到會自動喚醒 7、ThreadLocal,以及死鎖分析 hreadLocal為每個執行緒維護一個本地變數。  採用空間換時間,它用於執行緒間的資料隔離,為每一個使用該變數的執行緒提供一個副本,每個執行緒都可以獨立地改變自己的副本,而不會和其他執行緒的副本衝突。  ThreadLocal類中維護一個Map,用於儲存每一個執行緒的變數副本,Map中元素的鍵為執行緒物件,而值為對應執行緒的變數副本。  徹底理解ThreadLocal

8、Synchronized 與Lock ReentrantLock 擁有Synchronized相同的併發性和記憶體語義,此外還多了 鎖投票,定時鎖等候和中斷鎖等候  執行緒A和B都要獲取物件O的鎖定,假設A獲取了物件O鎖,B將等待A釋放對O的鎖定,  如果使用 synchronized ,如果A不釋放,B將一直等下去,不能被中斷  如果 使用ReentrantLock,如果A不釋放,可以使B在等待了足夠長的時間以後,中斷等待,而幹別的事情

ReentrantLock獲取鎖定與三種方式:  a) lock(), 如果獲取了鎖立即返回,如果別的執行緒持有鎖,當前執行緒則一直處於休眠狀態,直到獲取鎖  b) tryLock(), 如果獲取了鎖立即返回true,如果別的執行緒正持有鎖,立即返回false;  c)tryLock(long timeout,TimeUnit unit), 如果獲取了鎖定立即返回true,如果別的執行緒正持有鎖,會等待引數給定的時間,在等待的過程中,如果獲取了鎖定,就返回true,如果等待超時,返回false;  d) lockInterruptibly:如果獲取了鎖定立即返回,如果沒有獲取鎖定,當前執行緒處於休眠狀態,直到或者鎖定,或者當前執行緒被別的執行緒中斷

總體的結論先擺出來:

synchronized:  在資源競爭不是很激烈的情況下,偶爾會有同步的情形下,synchronized是很合適的。原因在於,編譯程式通常會盡可能的進行優化synchronized,另外可讀性非常好,不管用沒用過5.0多執行緒包的程式設計師都能理解。  ReentrantLock:  ReentrantLock提供了多樣化的同步,比如有時間限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在資源競爭不激烈的情形下,效能稍微比synchronized差點點。但是當同步非常激烈的時候,synchronized的效能一下子能下降好幾十倍。而ReentrantLock確還能維持常態。

詳解synchronized與Lock的區別與使用

9、Volatile和Synchronized Volatile和Synchronized四個不同點:

粒度不同,前者針對變數 ,後者鎖物件和類 syn阻塞,volatile執行緒不阻塞 syn保證三大特性,volatile不保證原子性 syn編譯器優化,volatile不優化  要使 volatile 變數提供理想的執行緒安全,必須同時滿足下面兩個條件:  對變數的寫操作不依賴於當前值。 該變數沒有包含在具有其他變數的不變式中。 JAVA多執行緒之volatile 與 synchronized 的比較

10、CAS CAS是樂觀鎖技術,當多個執行緒嘗試使用CAS同時更新同一個變數時,只有其中一個執行緒能更新變數的值,而其它執行緒都失敗,失敗的執行緒並不會被掛起,而是被告知這次競爭中失敗,並可以再次嘗試。CAS有3個運算元,記憶體值V,舊的預期值A,要修改的新值B。當且僅當預期值A和記憶體值V相同時,將記憶體值V修改為B,否則什麼都不做。

11、Java中Unsafe類詳解 通過Unsafe類可以分配記憶體,可以釋放記憶體;類中提供的3個本地方法allocateMemory、reallocateMemory、freeMemory分別用於分配記憶體,擴充記憶體和釋放記憶體,與C語言中的3個方法對應。 可以定位物件某欄位的記憶體位置,也可以修改物件的欄位值,即使它是私有的; 掛起與恢復:將一個執行緒進行掛起是通過park方法實現的,呼叫 park後,執行緒將一直阻塞直到超時或者中斷等條件出現。unpark可以終止一個掛起的執行緒,使其恢復正常。整個併發框架中對執行緒的掛起操作被封裝在 LockSupport類中,LockSupport類中有各種版本pack方法,但最終都呼叫了Unsafe.park()方法。 cas  Java中Unsafe類詳解 12、執行緒池 執行緒池的作用:  在程式啟動的時候就建立若干執行緒來響應處理,它們被稱為執行緒池,裡面的執行緒叫工作執行緒  第一:降低資源消耗。通過重複利用已建立的執行緒降低執行緒建立和銷燬造成的消耗。  第二:提高響應速度。當任務到達時,任務可以不需要等到執行緒建立就能立即執行。  第三:提高執行緒的可管理性。  常用執行緒池:ExecutorService 是主要的實現類,其中常用的有  Executors.newSingleT  hreadPool(),newFixedThreadPool(),newcachedTheadPool(),newScheduledThreadPool()。

13、ThreadPoolExecutor 構造方法引數說明 corePoolSize:核心執行緒數,預設情況下核心執行緒會一直存活,即使處於閒置狀態也不會受存keepAliveTime限制。除非將allowCoreThreadTimeOut設定為true。  maximumPoolSize:執行緒池所能容納的最大執行緒數。超過這個數的執行緒將被阻塞。當任務佇列為沒有設定大小的LinkedBlockingDeque時,這個值無效。  keepAliveTime:非核心執行緒的閒置超時時間,超過這個時間就會被回收。  unit:指定keepAliveTime的單位,如TimeUnit.SECONDS。當將allowCoreThreadTimeOut設定為true時對corePoolSize生效。  workQueue:執行緒池中的任務佇列.  常用的有三種佇列,SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue。

threadFactory:執行緒工廠,提供建立新執行緒的功能。ThreadFactory是一個介面,只有一個方法

原理 如果當前池大小 poolSize 小於 corePoolSize ,則建立新執行緒執行任務。 如果當前池大小 poolSize 大於 corePoolSize ,且等待佇列未滿,則進入等待佇列 如果當前池大小 poolSize 大於 corePoolSize 且小於 maximumPoolSize ,且等待佇列已滿,則建立新執行緒執行任務。 如果當前池大小 poolSize 大於 corePoolSize 且大於 maximumPoolSize ,且等待佇列已滿,則呼叫拒絕策略來處理該任務。 執行緒池裡的每個執行緒執行完任務後不會立刻退出,而是會去檢查下等待佇列裡是否還有執行緒任務需要執行,如果在 keepAliveTime 裡等不到新的任務了,那麼執行緒就會退出。 13、Executor拒絕策略 AbortPolicy:為java執行緒池預設的阻塞策略,不執行此任務,而且直接丟擲一個執行時異常,切記ThreadPoolExecutor.execute需要try  catch,否則程式會直接退出. DiscardPolicy:直接拋棄,任務不執行,空方法 DiscardOldestPolicy:從佇列裡面拋棄head的一個任務,並再次execute 此task。 CallerRunsPolicy:在呼叫execute的執行緒裡面執行此command,會阻塞入 使用者自定義拒絕策略:實現RejectedExecutionHandler,並自己定義策略模式 14、CachedThreadPool 、 FixedThreadPool、SingleThreadPool newSingleThreadExecutor :建立一個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務, 保證所有任務按照指定順序(FIFO, LIFO, 優先順序)執行 適用場景:任務少 ,並且不需要併發執行 newCachedThreadPool :建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒.  執行緒沒有任務要執行時,便處於空閒狀態,處於空閒狀態的執行緒並不會被立即銷燬(會被快取住),只有當空閒時間超出一段時間(預設為60s)後,執行緒池才會銷燬該執行緒(相當於清除過時的快取)。新任務到達後,執行緒池首先會讓被快取住的執行緒(空閒狀態)去執行任務,如果沒有可用執行緒(無空閒執行緒),便會建立新的執行緒。  適用場景:處理任務速度 > 提交任務速度,耗時少的任務(避免無限新增執行緒) newFixedThreadPool :建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。 newScheduledThreadPool:建立一個定長執行緒池,支援定時及週期性任務執行 15、CopyOnWriteArrayList CopyOnWriteArrayList : 寫時加鎖,當新增一個元素的時候,將原來的容器進行copy,複製出一個新的容器,然後在新的容器裡面寫,寫完之後再將原容器的引用指向新的容器,而讀的時候是讀舊容器的資料,所以可以進行併發的讀,但這是一種弱一致性的策略。  使用場景:CopyOnWriteArrayList適合使用在讀操作遠遠大於寫操作的場景裡,比如快取。

16、AQS AQS使用一個int成員變數來表示同步狀態,通過內建的FIFO佇列來完成獲取資源執行緒的排隊工作。 private volatile int state;//共享變數,使用volatile修飾保證執行緒可見性 1 2種同步方式:獨佔式,共享式。獨佔式如ReentrantLock,共享式如Semaphore,CountDownLatch,組合式的如ReentrantReadWriteLock 節點的狀態  CANCELLED,值為1,表示當前的執行緒被取消;  SIGNAL,值為-1,表示當前節點的後繼節點包含的執行緒需要執行,也就是unpark;  CONDITION,值為-2,表示當前節點在等待condition,也就是在condition佇列中;  PROPAGATE,值為-3,表示當前場景下後續的acquireShared能夠得以執行;  值為0,表示當前節點在sync佇列中,等待著獲取鎖。 模板方法模式   protected boolean tryAcquire(int arg) : 獨佔式獲取同步狀態,試著獲取,成功返回true,反之為false   protected boolean tryRelease(int arg) :獨佔式釋放同步狀態,等待中的其他執行緒此時將有機會獲取到同步狀態;   protected int tryAcquireShared(int arg) :共享式獲取同步狀態,返回值大於等於0,代表獲取成功;反之獲取失敗;   protected boolean tryReleaseShared(int arg) :共享式釋放同步狀態,成功為true,失敗為false  AQS維護一個共享資源state,通過內建的FIFO來完成獲取資源執行緒的排隊工作。該佇列由一個一個的Node結點組成,每個Node結點維護一個prev引用和next引用,分別指向自己的前驅和後繼結點。雙端雙向連結串列。  獨佔式:樂觀的併發策略  acquire   a.首先tryAcquire獲取同步狀態,成功則直接返回;否則,進入下一環節;  b.執行緒獲取同步狀態失敗,就構造一個結點,加入同步佇列中,這個過程要保證執行緒安全;   c.加入佇列中的結點執行緒進入自旋狀態,若是老二結點(即前驅結點為頭結點),才有機會嘗試去獲取同步狀態;否則,當其前驅結點的狀態為SIGNAL,執行緒便可安心休息,進入阻塞狀態,直到被中斷或者被前驅結點喚醒。  release  release的同步狀態相對簡單,需要找到頭結點的後繼結點進行喚醒,若後繼結點為空或處於CANCEL狀態,從後向前遍歷找尋一個正常的結點,喚醒其對應執行緒。 共享式:  共享式地獲取同步狀態.同步狀態的方法tryAcquireShared返回值為int。  a.當返回值大於0時,表示獲取同步狀態成功,同時還有剩餘同步狀態可供其他執行緒獲取;   b.當返回值等於0時,表示獲取同步狀態成功,但沒有可用同步狀態了;   c.當返回值小於0時,表示獲取同步狀態失敗。 AQS實現公平鎖和非公平鎖  非公平鎖中,那些嘗試獲取鎖且尚未進入等待佇列的執行緒會和等待佇列head結點的執行緒發生競爭。公平鎖中,在獲取鎖時,增加了isFirst(current)判斷,當且僅當,等待佇列為空或當前執行緒是等待佇列的頭結點時,才可嘗試獲取鎖。   Java併發包基石-AQS詳解 16、Java裡的阻塞佇列 7個阻塞佇列。分別是 ArrayBlockingQueue :一個由陣列結構組成的有界阻塞佇列。  LinkedBlockingQueue :一個由連結串列結構組成的有界阻塞佇列。  PriorityBlockingQueue :一個支援優先順序排序的無界阻塞佇列。  DelayQueue:一個使用優先順序佇列實現的無界阻塞佇列。  SynchronousQueue:一個不儲存元素的阻塞佇列。  LinkedTransferQueue:一個由連結串列結構組成的無界阻塞佇列。  LinkedBlockingDeque:一個由連結串列結構組成的雙向阻塞佇列。

新增元素 Java中的阻塞佇列介面BlockingQueue繼承自Queue介面。BlockingQueue介面提供了3個新增元素方法。  add:新增元素到佇列裡,新增成功返回true,由於容量滿了新增失敗會丟擲IllegalStateException異常  offer:新增元素到佇列裡,新增成功返回true,新增失敗返回false  put:新增元素到佇列裡,如果容量滿了會阻塞直到容量不滿

刪除方法 3個刪除方法  poll:刪除佇列頭部元素,如果佇列為空,返回null。否則返回元素。  remove:基於物件找到對應的元素,並刪除。刪除成功返回true,否則返回false  take:刪除佇列頭部元素,如果佇列為空,一直阻塞到佇列有元素並刪除

17、condition 對Condition的原始碼理解,主要就是理解等待佇列,等待佇列可以類比同步佇列,而且等待佇列比同步佇列要簡單,因為等待佇列是單向佇列,同步佇列是雙向佇列。

java condition使用及分

18、DelayQueue 佇列中每個元素都有個過期時間,並且佇列是個優先順序佇列,當從佇列獲取元素時候,只有過期元素才會出佇列。

併發佇列-無界阻塞延遲佇列delayqueue原理探究

19、Fork/Join框架  Fork/Join框架是Java 7提供的一個用於並行執行任務的框架,是一個把大任務分割成若干個小任務,最終彙總每個小任務結果後得到大任務結果的框架。Fork/Join框架要完成兩件事情:

  1.任務分割:首先Fork/Join框架需要把大的任務分割成足夠小的子任務,如果子任務比較大的話還要對子任務進行繼續分割

  2.執行任務併合並結果:分割的子任務分別放到雙端佇列裡,然後幾個啟動執行緒分別從雙端佇列裡獲取任務執行。子任務執行完的結果都放在另外一個佇列裡,啟動一個執行緒從佇列裡取資料,然後合併這些資料。

  在Java的Fork/Join框架中,使用兩個類完成上述操作

  1.ForkJoinTask:我們要使用Fork/Join框架,首先需要建立一個ForkJoin任務。該類提供了在任務中執行fork和join的機制。通常情況下我們不需要直接整合ForkJoinTask類,只需要繼承它的子類,Fork/Join框架提供了兩個子類:

    a.RecursiveAction:用於沒有返回結果的任務

    b.RecursiveTask:用於有返回結果的任務

  2.ForkJoinPool:ForkJoinTask需要通過ForkJoinPool來執行

  任務分割出的子任務會新增到當前工作執行緒所維護的雙端佇列中,進入佇列的頭部。當一個工作執行緒的佇列裡暫時沒有任務時,它會隨機從其他工作執行緒的佇列的尾部獲取一個任務(工作竊取演算法)。  Fork/Join框架的實現原理    ForkJoinPool由ForkJoinTask陣列和ForkJoinWorkerThread陣列組成,ForkJoinTask陣列負責將存放程式提交給ForkJoinPool,而ForkJoinWorkerThread負責執行這

20、原子操作類 在java.util.concurrent.atomic包下,可以分為四種類型的原子更新類:原子更新基本型別、原子更新陣列型別、原子更新引用和原子更新屬性。

原子更新基本型別  使用原子方式更新基本型別,共包括3個類:  AtomicBoolean:原子更新布林變數  AtomicInteger:原子更新整型變數  AtomicLong:原子更新長整型變數 原子更新陣列  通過原子更新數組裡的某個元素,共有3個類:  AtomicIntegerArray:原子更新整型陣列的某個元素  AtomicLongArray:原子更新長整型陣列的某個元素  AtomicReferenceArray:原子更新引用型別陣列的某個元素  AtomicIntegerArray常用的方法有:  int addAndSet(int i, int delta):以原子方式將輸入值與陣列中索引為i的元素相加  boolean compareAndSet(int i, int expect, int update):如果當前值等於預期值,則以原子方式更新陣列中索引為i的值為update值 原子更新引用型別  AtomicReference:原子更新引用型別  AtomicReferenceFieldUpdater:原子更新引用型別裡的欄位  AtomicMarkableReference:原子更新帶有標記位的引用型別。 原子更新欄位類  如果需要原子更新某個類的某個欄位,就需要用到原子更新欄位類,可以使用以下幾個類:  AtomicIntegerFieldUpdater:原子更新整型欄位  AtomicLongFieldUpdater:原子更新長整型欄位  AtomicStampedReference:原子更新帶有版本號的引用型別。  要想原子更新欄位,需要兩個步驟:  每次必須使用newUpdater建立一個更新器,並且需要設定想要更新的類的欄位  更新類的欄位(屬性)必須為public volatile 21、同步屏障CyclicBarrier CyclicBarrier 的字面意思是可迴圈使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組執行緒到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續幹活。CyclicBarrier預設的構造方法是CyclicBarrier(int parties),其引數表示屏障攔截的執行緒數量,每個執行緒呼叫await方法告訴CyclicBarrier我已經到達了屏障,然後當前執行緒被阻塞。  CyclicBarrier和CountDownLatch的區別

CountDownLatch的計數器只能使用一次。而CyclicBarrier的計數器可以使用reset() 方法重置。所以CyclicBarrier能處理更為複雜的業務場景,比如如果計算髮生錯誤,可以重置計數器,並讓執行緒們重新執行一次。  CyclicBarrier還提供其他有用的方法,比如getNumberWaiting方法可以獲得CyclicBarrier阻塞的執行緒數量。isBroken方法用來知道阻塞的執行緒是否被中斷。比如以下程式碼執行完之後會返回true。

22、Semaphore Semaphore(訊號量)是用來控制同時訪問特定資源的執行緒數量,它通過協調各個執行緒,以保證合理的使用公共資源  Semaphore可以用於做流量控制,特別公用資源有限的應用場景,比如資料庫連線。假如有一個需求,要讀取幾萬個檔案的資料,因為都是IO密集型任務,我們可以啟動幾十個執行緒併發的讀取,但是如果讀到記憶體後,還需要儲存到資料庫中,而資料庫的連線數只有10個,這時我們必須控制只有十個執行緒同時獲取資料庫連線儲存資料,否則會報錯無法獲取資料庫連線。這個時候,我們就可以使用Semaphore來做流控,程式碼如下:

控制併發執行緒數的Semaphore

23、死鎖,以及解決死鎖 死鎖產生的四個必要條件 互斥條件:資源是獨佔的且排他使用,程序互斥使用資源,即任意時刻一個資源只能給一個程序使用,其他程序若申請一個資源,而該資源被另一程序佔有時,則申請者等待直到資源被佔有者釋放。  不可剝奪條件:程序所獲得的資源在未使用完畢之前,不被其他程序強行剝奪,而只能由獲得該資源的程序資源釋放。  請求和保持條件:程序每次申請它所需要的一部分資源,在申請新的資源的同時,繼續佔用已分配到的資源。  迴圈等待條件:在發生死鎖時必然存在一個程序等待佇列{P1,P2,…,Pn},其中P1等待P2佔有的資源,P2等待P3佔有的資源,…,Pn等待P1佔有的資源,形成一個程序等待環路,環路中每一個程序所佔有的資源同時被另一個申請,也就是前一個程序佔有後一個程序所深情地資源。

解決死鎖 一是死鎖預防,就是不讓上面的四個條件同時成立。  二是,合理分配資源。  三是使用銀行家演算法,如果該程序請求的資源作業系統剩餘量可以滿足,那麼就分配。

24、程序間的通訊方式 管道( pipe):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。 有名管道 (named pipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。 訊號量( semophore ) : 訊號量是一個計數器,可以用來控制多個程序對共享資源的訪問。它常作為一種鎖機制,防止某程序正在訪問共享資源時,其他程序也訪問該資源。因此,主要作為程序間以及同一程序內不同執行緒之間的同步手段。 訊息佇列( message queue ) : 訊息佇列是由訊息的連結串列,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。 訊號 ( sinal ) : 訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。 共享記憶體( shared memory ) :共享記憶體就是對映一段能被其他程序所訪問的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以訪問。共享記憶體是最快的 IPC 方式,它是針對其他程序間通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號量,配合使用,來實現程序間的同步和通訊。 套接字( socket ) : 套解口也是一種程序間通訊機制,與其他通訊機制不同的是,它可用於不同機器間的程序通訊。 中斷 interrupt()的作用是中斷本執行緒。  本執行緒中斷自己是被允許的;其它執行緒呼叫本執行緒的interrupt()方法時,會通過checkAccess()檢查許可權。這有可能丟擲SecurityException異常。  如果本執行緒是處於阻塞狀態:呼叫執行緒的wait(), wait(long)或wait(long, int)會讓它進入等待(阻塞)狀態,或者呼叫執行緒的join(), join(long), join(long, int), sleep(long), sleep(long, int)也會讓它進入阻塞狀態。若執行緒在阻塞狀態時,呼叫了它的interrupt()方法,那麼它的“中斷狀態”會被清除並且會收到一個InterruptedException異常。例如,執行緒通過wait()進入阻塞狀態,此時通過interrupt()中斷該執行緒;呼叫interrupt()會立即將執行緒的中斷標記設為“true”,但是由於執行緒處於阻塞狀態,所以該“中斷標記”會立即被清除為“false”,同時,會產生一個InterruptedException的異常。  如果執行緒被阻塞在一個Selector選擇器中,那麼通過interrupt()中斷它時;執行緒的中斷標記會被設定為true,並且它會立即從選擇操作中返回。  如果不屬於前面所說的情況,那麼通過interrupt()中斷執行緒時,它的中斷標記會被設定為“true”。  中斷一個“已終止的執行緒”不會產生任何操作。

終止處於“阻塞狀態”的執行緒  通常,我們通過“中斷”方式終止處於“阻塞狀態”的執行緒。  當執行緒由於被呼叫了sleep(), wait(), join()等方法而進入阻塞狀態;若此時呼叫執行緒的interrupt()將執行緒的中斷標記設為true。由於處於阻塞狀態,中斷標記會被清除,同時產生一個InterruptedException異常。將InterruptedException放在適當的為止就能終止執行緒,  終止處於“執行狀態”的執行緒 interrupted() 和 isInterrupted()的區別 最後談談 interrupted() 和 isInterrupted()。  interrupted() 和 isInterrupted()都能夠用於檢測物件的“中斷標記”。  區別是,interrupted()除了返回中斷標記之外,它還會清除中斷標記(即將中斷標記設為false);而isInterrupted()僅僅返回中斷標記。  interrupt()和執行緒終止方式 ---------------------  作者:行者路上  來源:CSDN  原文:https://blog.csdn.net/u012998254/article/details/79400549  版權宣告:本文為博主原創文章,轉載請附上博文連結!