假設有兩個線程在并發運行,一個線程執行的代碼中含有一個死循環如:while(true)....當該線程在執行while(true)中代碼時,另一個線程會有機會執行嗎?
示例代碼(代碼來源于互聯網)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Service { Object object1 = new Object(); public void methodA() { synchronized (object1) { System.out.println( "methodA begin" ); boolean isContinueRun = true ; //在這里執行一個死循環 while (isContinueRun) { } System.out.println( "methodA end" ); } } Object object2 = new Object(); public void methodB() { synchronized (object2) { System.out.println( "methodB begin" ); System.out.println( "methodB end" ); } } } |
兩個線程類的實現如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import service.Service; public class ThreadA extends Thread { private Service service; public ThreadA(Service service) { super (); this .service = service; } @Override public void run() { service.methodA(); } } |
線程A執行methodA(),methodA()中有一個死循環
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import service.Service; public class ThreadB extends Thread { private Service service; public ThreadB(Service service) { super (); this .service = service; } @Override public void run() { service.methodB(); } } |
線程B執行methodB(),當線程A進入methodA()中的while死循環時,線程B的能不能執行完成?
測試類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import service.Service; import extthread.ThreadA; import extthread.ThreadB; public class Run { public static void main(String[] args) { Service service = new Service(); ThreadA athread = new ThreadA(service); athread.start(); ThreadB bthread = new ThreadB(service); bthread.start(); } } |
由于線程A和線程B獲得的對象鎖不是同一把鎖,從結果中可以看出,線程B是可以執行完成的。而線程A由于進入了while死循環,故線程A一直執行運行下去了(整個程序未結束),但線程B會結束。
也就是說,盡管線程A一直在while中執行,需要占用CPU。但是,線程的調度是由JVM或者說是操作系統來負責的,并不是說線程A一直在while循環,然后線程B就占用不到CPU了。對于線程A而言,它就相當于一個“計算密集型”作業了。如果我們的while循環是不斷地測試某個條件是否成立,那么這種方式就很浪費CPU,可參考一個具體的實例:JAVA多線程之線程間的通信方式 中的“線程間的通信方式”第二點while輪詢。
如果把Service.java修改成如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Service { // Object object1 = new Object(); public void methodA() { synchronized ( this ) { System.out.println( "methodA begin" ); boolean isContinueRun = true ; //在這里執行一個死循環 while (isContinueRun) { } System.out.println( "methodA end" ); } } // Object object2 = new Object(); public void methodB() { synchronized ( this ) { System.out.println( "methodB begin" ); System.out.println( "methodB end" ); } } } |
若線程A先獲得對象鎖時,由于while循環,線程A一直在while空循環中。而線程B也因為無法獲得鎖而執行不了methodB()。
可以看出,如果在一個線程在synchronized方法中無法退出,無法將鎖釋放,另一個線程就只能無限等待了。
以上就是本文的全部內容,希望對大家學習java多線程有所幫助。