一,問題描述
假設有兩個線程在並發運行,一個線程執行的代碼中含有一個死循環如:while(true)....當該線程在執行while(true)中代碼時,另一個線程會有機會執行嗎?
二,示例代碼(代碼來源於互聯網)
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");
}
}
}
兩個線程類的實現如下:
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()中有一個死循環
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的能不能執行完成?
測試類
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了。
如果把Service.java修改成如下:
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方法中無法退出,無法將鎖釋放,另一個線程就只能無限等待了。