歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java多線程之當一個線程在執行死循環時會影響另外一個線程嗎?

一,問題描述

假設有兩個線程在並發運行,一個線程執行的代碼中含有一個死循環如: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方法中無法退出,無法將鎖釋放,另一個線程就只能無限等待了。

Copyright © Linux教程網 All Rights Reserved