Java多线程编程核心技术(第3版)
上QQ阅读APP看书,第一时间看更新

2.2.18 synchronized方法无限等待问题与解决方案

使用同步方法会导致锁资源被长期占用,得不到运行的机会。创建示例项目twoStop,类Service.java代码如下:


package service;

public class Service {
synchronized public void methodA() {
    System.out.println("methodA begin");
    boolean isContinueRun = true;
    while (isContinueRun) {
    }
    System.out.println("methodA end");
}

synchronized public void methodB() {
    System.out.println("methodB begin");
    System.out.println("methodB end");
}
}

两个自定义线程类代码如图2-53所示。

图2-53 自定义线程类代码

运行类Run.java代码如下:


package test.run;

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();
}

}

程序运行结果如图2-54所示。

图2-54 运行结果是死循环

ThreadB永远得不到运行的机会,这时就可以使用同步块来解决这个问题,更改后的Service.java文件代码如下:


package service;

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");
    }
}
}

程序运行结果如图2-55所示。

图2-55 不再出现同步等待的情况

本示例代码在项目twoNoStop中。