主要实现功能是:使用两个线程循环打印AB。
出现的问题:当调用PrintB中的run()时,通过Debug模式调试发现,是先进入循环体,再进行的条件判断,导致最后的结果就会多输出一次数据。
源码如下:
线程共享资源:Printer
/**
* 共享资源:打印机
* @author Tangxkun
*
*/
public class Printer {
//最大打印次数
private final int MAX_COUNT = 5;
//false表示该打印机未打印A,true表示该打印机正在打印A
private boolean printingA = false;
private int count = 0;
public synchronized void printA(){
System.out.println(count++);
printingA = true;
System.out.println("A");
notifyAll();
}
public synchronized void printB(){
System.out.println(count++);
printingA = false;
System.out.println("B");
notifyAll();
}
public synchronized void aWaiting() throws InterruptedException{
while(printingA == true){
wait();
}
}
public synchronized void bWaiting() throws InterruptedException{
while(printingA == false){
wait();
}
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getMAX_COUNT() {
return MAX_COUNT;
}
}
打印A的线程任务:
/**
* 打印A的线程
* @author Tangxkun
*
*/
public class PrintA implements Runnable{
private Printer printer;
public PrintA(Printer printer) {
super();
this.printer = printer;
}
@Override
public void run() {
while(printer.getCount() < printer.getMAX_COUNT()){
printer.printA();
try {
printer.aWaiting();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
打印B的线程任务:
/**
* 打印B的线程
* @author Tangxkun
*
*/
public class PrintB implements Runnable{
private Printer printer;
public PrintB(Printer printer) {
super();
this.printer = printer;
}
@Override
public void run() {
while(printer.getCount() < printer.getMAX_COUNT()){
try {
printer.bWaiting();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
printer.printB();
}
}
}
测试代码:
/**
* 测试代码
* @author Tangxkun
*
*/
public class Test {
public static void main(String[] args) {
Printer printer = new Printer();
PrintA printA = new PrintA(printer);
PrintB printB = new PrintB(printer);
Thread threadA = new Thread(printA,"A");
Thread threadB = new Thread(printB, "B");
threadA.start();
threadB.start();
}
}
当设置MAX_COUNT=5时,输出结果为:
当设置MAX_COUNT=6时,输出结果为:
当设置MAX_COUNT=7时,输出结果为:
烧脑了半天还是没有找出端倪,所以来请教一下各位大神!
原因终于找到了,是自己没有理解清楚线程挂起的概念。第一次执行线程B的时候,会while条件判断进入,然后挂起,并没有执行printer.printB(),当线程A唤醒线程B时,线程B从挂起时刻的代码处继续往后执行(执行printer.printB(),完成之前被挂起的任务),而不是重新开始执行run(),也就是说,不会再进行while条件判断,最后再次进入while循环。