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方法中無法退出,無法將鎖釋放,另一個線程就只能無限等待了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM