JAVA多執行緒之當一個執行緒在執行死迴圈時會影響另外一個執行緒嗎?
一,問題描述
假設有兩個執行緒在併發執行,一個執行緒執行的程式碼中含有一個死迴圈如:while(true)....當該執行緒在執行while(true)中程式碼時,另一個執行緒會有機會執行嗎?
二,示例程式碼(程式碼來源於網際網路)
1 public class Service { 2 Object object1 = new Object(); 3 4 public void methodA() { 5 synchronized (object1) { 6 System.out.println("methodA begin");7 boolean isContinueRun = true; 8 //在這裡執行一個死迴圈 9 while (isContinueRun) { 10 11 } 12 System.out.println("methodA end"); 13 } 14 } 15 16 Object object2 = new Object(); 17 18 public void methodB() {19 synchronized (object2) { 20 System.out.println("methodB begin"); 21 System.out.println("methodB end"); 22 } 23 } 24 }
兩個執行緒類的實現如下:
1 import service.Service; 2 3 public class ThreadA extends Thread { 4 5 private Service service;6 7 public ThreadA(Service service) { 8 super(); 9 this.service = service; 10 } 11 12 @Override 13 public void run() { 14 service.methodA(); 15 } 16 17 }
執行緒A執行methodA(),methodA()中有一個死迴圈
1 import service.Service; 2 3 public class ThreadB extends Thread { 4 5 private Service service; 6 7 public ThreadB(Service service) { 8 super(); 9 this.service = service; 10 } 11 12 @Override 13 public void run() { 14 service.methodB(); 15 } 16 17 }
執行緒B執行methodB(),當執行緒A進入methodA()中的while死迴圈時,執行緒B的能不能執行完成?
測試類
1 import service.Service; 2 import extthread.ThreadA; 3 import extthread.ThreadB; 4 5 public class Run { 6 7 public static void main(String[] args) { 8 Service service = new Service(); 9 10 ThreadA athread = new ThreadA(service); 11 athread.start(); 12 13 ThreadB bthread = new ThreadB(service); 14 bthread.start(); 15 } 16 17 }
執行結果:
由於執行緒A和執行緒B獲得的物件鎖不是同一把鎖,從結果中可以看出,執行緒B是可以執行完成的。而執行緒A由於進入了while死迴圈,故執行緒A一直執行執行下去了(整個程式未結束),但執行緒B會結束。
也就是說,儘管執行緒A一直在while中執行,需要佔用CPU。但是,執行緒的排程是由JVM或者說是作業系統來負責的,並不是說執行緒A一直在while迴圈,然後執行緒B就佔用不到CPU了。對於執行緒A而言,它就相當於一個“計算密集型”作業了。如果我們的while迴圈是不斷地測試某個條件是否成立,那麼這種方式就很浪費CPU,可參考一個具體的例項:JAVA多執行緒之執行緒間的通訊方式 中的“執行緒間的通訊方式”第二點while輪詢。
如果把Service.java修改成如下:
1 public class Service { 2 // Object object1 = new Object(); 3 4 public void methodA() { 5 synchronized (this) { 6 System.out.println("methodA begin"); 7 boolean isContinueRun = true; 8 //在這裡執行一個死迴圈 9 while (isContinueRun) { 10 11 } 12 System.out.println("methodA end"); 13 } 14 } 15 16 // Object object2 = new Object(); 17 18 public void methodB() { 19 synchronized (this) { 20 System.out.println("methodB begin"); 21 System.out.println("methodB end"); 22 } 23 } 24 }
若執行緒A先獲得物件鎖時,由於while迴圈,執行緒A一直在while空迴圈中。而執行緒B也因為無法獲得鎖而執行不了methodB()。
可以看出,如果在一個執行緒在synchronized方法中無法退出,無法將鎖釋放,另一個執行緒就只能無限等待了。
相關推薦
JAVA多執行緒之當一個執行緒在執行死迴圈時會影響另外一個執行緒嗎?
一,問題描述 假設有兩個執行緒在併發執行,一個執行緒執行的程式碼中含有一個死迴圈如:while(true)....當該執行緒在執行while(true)中程式碼時,另一個執行緒會有機會執行嗎? 二,示例程式碼(程式碼來源於網際網路) 1 public class Service { 2
關於主執行緒中自動建立的Looper的思考:主執行緒中Looper中的輪詢死迴圈為何沒有阻塞主執行緒
Android中UI執行緒會自動給我們建立一個looper,但是looper中的loop方法是個死迴圈.為什麼我們在UI執行緒中寫的程式碼為何都能順利執行?為什麼沒有引起ANR呢? Looper的部分原始碼: /** * Initial
中斷含有死迴圈和sleep的子執行緒(java.lang.InterruptedException: sleep interrupted)
【轉載】:https://blog.csdn.net/qq_33291307/article/details/78804781 死迴圈執行緒中包含sleep,無法中斷執行緒:在sleep前面新增Thread.current.isInterrupt判斷,跳出死迴圈,因為sleep本身是丟擲一個int
java多線程(4)模擬排隊叫號程序,不能出現交替執行的結果
pac main program chapter java desc class void sta package com.javaconcurrencyprogramming.chapter1;/** * @description: 模擬有錯誤的排隊叫號程序 * @aut
JAVA多線程之先行發生原則
程序 sync 影響 cnblogs 代碼 之間 發生 變量 nal 一、引子 如果java內存模型中所有的有序性都僅僅依靠volatile和synchronized來完成,那麽有一些操作會變得很繁瑣,但我們在編寫java並發代碼時並未感覺到這一點,這是因為java
JAVA多線程之volatile 與 synchronized 的比較
@override effect process 棧空間 完成 內存可見性 沒有 hash 主從 一,volatile關鍵字的可見性 要想理解volatile關鍵字,得先了解下JAVA的內存模型,Java內存模型的抽象示意圖如下: 從圖中可以看出: ①每個線程都有一個自己的
JAVA多線程之線程間的通信方式
關系 strong while nal socket 計數 緩沖 str 進行 線程間的通信方式 ①同步 這裏講的同步是指多個線程通過synchronized關鍵字這種方式來實現線程間的通信。 ②while輪詢的方式 ③wait/notify機制 ④管道通信就是使用java
java線程-java多線程之可見性
log bsp 共享 一份 .com tro 最小 原子 java語言 可見性:一個線程對共享變量值的修改,能夠及時唄其他線程看到。 共享變量:如果一個變量在多個線程的內存中都存在副本,那麽這個變量就是這幾個線程的共享變量。 java內存模型(JMM) 描述了java程序中
JAVA多線程之CountDownLatch
業務 block ron log 分享 extends 發現 info interrupt 前序: 上周測試給開發的同事所開發的模塊提出了一個bug,並且還是偶現。 經過仔細查看代碼,發現是在業務中啟用了多線程,2個線程同時跑,但是新啟動的2個線程必須保證一個完成之後另一個
Java多線程之捕獲子線程中的異常---面試經
正常的 current service handle AD 希望 article 程序 UNC 在某些場景下,我們經常需要使用多線程來執行任務提高性能,但是我們知道正常的主線程是無法處理子線程的異常的,一旦出現異常就會傳播到控制臺。這個時候我們需要在線程裏面處理異常怎麽辦呢
Java多線程之---用 CountDownLatch 說明 AQS 的實現原理
行操作 support exce indicate next unpark compare turn images 本文基於 jdk 1.8 。 CountDownLatch 的使用 前面的文章中說到了 volatile 以及用 volatile 來實現自旋鎖,例如 j
java 多線程之取消與關閉
ket execute 是否 擁有 函數 恢復 響應 lean shu 要使線程安全,快速,可靠的停下來並不是一件容易的事情。java並沒有提供任何機制來安全的終止線程。但是java提供了中斷(interrupt)使一個線程可以終止另一個線程的當前工作 每個線程都有
java多線程之線程安全
發生 stack 經典 eat int create 加鎖 情況 zed 線程安全和非線程安全是多線程的經典問題,非線程安全會在多個線程對同一個對象並發訪問時發生。 註意1: 非線程安全的問題存在於實例變量中,如果是方法內部的私有變量,則不存在非線程安全問題。 實例變量是對
JAVA多線程之Synchronize 關鍵字原理
exc 成功 width origin www word 存在 方案 嘗試 image 眾所周知 Synchronize 關鍵字是解決並發問題常用解決方案,有以下三種使用方式: 同步普通方法,鎖的是當前對象。 同步靜態方法,鎖的是當前 Class 對象。 同步塊,鎖
Java多線程之深入理解synchronize關鍵字
tracking 而不是 方法 獲得 content cal art track () synchronize鎖重入: 關鍵字synchronize擁有鎖重入的功能,也就是在使用synchronize時,當一個線程的得到了一個對象的鎖後,再次請求此對象是可以再次得到
Java多線程之二(Synchronized)
clas 虛擬機 語句 sta 順序 this 基本 出現 一個 常用API method 註釋 run() run()方法是我們創建線程時必須要實現的方法,但是實際上該方法只是一個普通方法,直接調用並沒有開啟線程的作用。 start() start()方
Java多線程之三volatile與等待通知機制示例
不存在 跳出循環 三種 安全 同步 完成後 了解 try code 原子性,可見性與有序性 在多線程中,線程同步的時候一般需要考慮原子性,可見性與有序性 原子性 原子性定義:一個操作或者多個操作在執行過程中要麽全部執行完成,要麽全部都不執行,不存在執行一部分的情況。 以我們
伺服器無法繼續執行該事務,此會話中的活動事務已由另外一個會話提交或終止。
//執行事務處理 public void DoTran() { //建立連線並開啟 SqlConnection myConn=GetConn(); myConn.Open(); SqlCommand myComm=new SqlCo
Android UI 執行緒Loop.loop()死迴圈為啥沒有阻塞主執行緒?
要完全徹底理解這個問題,需要準備以下4方面的知識:Process/Thread,Android Binder IPC,Handler/Looper/MessageQueue訊息機制,Linux pipe/epoll機制。總結一下樓主主要有3個疑惑:1.Android中為什麼主執行緒不會因為Looper.loo
Java多線程之volatile
class 單用戶 用戶 修飾 ava tar true java多線 代碼 問題 Peterson算法是一個實現互斥鎖的並發程序設計算法,可以控制兩個線程訪問一個共享的單用戶資源而不發生訪問沖突。 參照《現代操作系統》,用Java實現了Peterson算法。 public