1. 程式人生 > >JAVA多執行緒之當一個執行緒在執行死迴圈時會影響另外一個執行緒嗎?

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