Java中一個(gè)線程執(zhí)行死循環(huán)有什么后果
假設(shè)有兩個(gè)線程在并發(fā)運(yùn)行,一個(gè)線程執(zhí)行的代碼中含有一個(gè)死循環(huán)如:while(true)....當(dāng)該線程在執(zhí)行while(true)中代碼時(shí),另一個(gè)線程會(huì)有機(jī)會(huì)執(zhí)行嗎?
示例代碼(代碼來(lái)源于互聯(lián)網(wǎng))
public class Service { Object object1 = new Object(); public void methodA() { synchronized (object1) { System.out.println("methodA begin"); boolean isContinueRun = true; //在這里執(zhí)行一個(gè)死循環(huán) 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"); } } }
兩個(gè)線程類的實(shí)現(xiàn)如下:
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執(zhí)行methodA(),methodA()中有一個(gè)死循環(huán)
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執(zhí)行methodB(),當(dāng)線程A進(jìn)入methodA()中的while死循環(huán)時(shí),線程B的能不能執(zhí)行完成?
測(cè)試類
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獲得的對(duì)象鎖不是同一把鎖,從結(jié)果中可以看出,線程B是可以執(zhí)行完成的。而線程A由于進(jìn)入了while死循環(huán),故線程A一直執(zhí)行運(yùn)行下去了(整個(gè)程序未結(jié)束),但線程B會(huì)結(jié)束。
也就是說(shuō),盡管線程A一直在while中執(zhí)行,需要占用CPU。但是,線程的調(diào)度是由JVM或者說(shuō)是操作系統(tǒng)來(lái)負(fù)責(zé)的,并不是說(shuō)線程A一直在while循環(huán),然后線程B就占用不到CPU了。對(duì)于線程A而言,它就相當(dāng)于一個(gè)“計(jì)算密集型”作業(yè)了。如果我們的while循環(huán)是不斷地測(cè)試某個(gè)條件是否成立,那么這種方式就很浪費(fèi)CPU,可參考一個(gè)具體的實(shí)例:JAVA多線程之線程間的通信方式 中的“線程間的通信方式”第二點(diǎn)while輪詢。
如果把Service.java修改成如下:
public class Service { // Object object1 = new Object(); public void methodA() { synchronized (this) { System.out.println("methodA begin"); boolean isContinueRun = true; //在這里執(zhí)行一個(gè)死循環(huán) 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先獲得對(duì)象鎖時(shí),由于while循環(huán),線程A一直在while空循環(huán)中。而線程B也因?yàn)闊o(wú)法獲得鎖而執(zhí)行不了methodB()。
可以看出,如果在一個(gè)線程在synchronized方法中無(wú)法退出,無(wú)法將鎖釋放,另一個(gè)線程就只能無(wú)限等待了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)java多線程有所幫助。
相關(guān)文章
解決Process.getInputStream()阻塞的問(wèn)題
這篇文章主要介紹了解決Process.getInputStream()阻塞的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06升級(jí)dubbo2.7.4.1版本平滑遷移到注冊(cè)中心nacos
這篇文章主要為大家介紹了2.7.4.1的dubbo平滑遷移到注冊(cè)中心nacos的兩種版本升級(jí)方案,以及為什要升級(jí),有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-02-02