一个线程打印A,一个线程打印B,一个线程打印C,实现循环打印ABC 10次。主函数有个小地方不懂!

新手上路,请多包涵
/*功能:三个线程,一个打印A,一个打印B,一个打印C,主函数实现循环打印ABCABCABCABC...  共打印10次ABC*/

public class ThreadABC {
    public static void main(String[] args) {
        Print p = new Print();
        
        /*打印A的进程*/
        new Thread(new Runnable() {
            public void run() {
                for(int i = 0;i <10;++i){//我设置的i打印10次啊
                    p.print_A();
        /*为什么只打印 5 次???!!!*/
        /*加上下面这行代码,就能正常打印10次,why???*/
                    //try{Thread.sleep();}catch(Exception e){;}
                }
                
            }
        }).start();
        
        /*启动打印B的线程*/
        new Thread(new Runnable() {
            public void run() {
                while(true)
                p.print_B();
            }
        }).start();
        
        /*启动打印C的线程*/
        new Thread(new Runnable() {
            public void run() {
                while(true)
                p.print_C();
            }
        }).start();
    }
}

/**/
class Print {
    /*flag用来同步*/
    private int flag = 1;
    /*打印 A */
    synchronized void print_A() {
        
        if(flag == 1) {
            System.out.print("A");
            flag = 2;
            try {this.notifyAll();}catch(Exception e) {e.printStackTrace();}
        }
        else {
            try {this.wait();}catch(Exception e) {e.printStackTrace();}
        }
    }
    /*打印B*/
    synchronized void print_B() {
        if(flag == 2) {
            System.out.print("B");
            flag = 3;
            try {this.notifyAll();}catch(Exception e) {e.printStackTrace();}
        }
        else {
            try {this.wait();}catch(Exception e) {e.printStackTrace();}
        }
    }
    /*打印C*/
        synchronized void print_C() {
        if(flag == 3) {
            System.out.println("C");
            flag = 1;
            try {this.notifyAll();}catch(Exception e) {e.printStackTrace();}
        }
        else {
            try {this.wait();}catch(Exception e) {e.printStackTrace();}
        }
    }
}
阅读 3.8k
2 个回答

1:首先指出代码的小问题——p变量应该是final类型,否则实现了Runnable接口的匿名内部类是访问不到的;

2:这个代码实现有点问题,打印A的线程一直循环,但是实际打印A的线程是依赖flag的值,并且flag的值在打印B/C的线程都有修改,问题就出在这,试想执行了一次print_A后,如若没有你添加的sleep等待,循环回来继续执行print_A,但是此时flag已经被打印B的线程改成了3,但是打印C的线程还没执行完,flag还是3,然后notify唤醒print_A,但是flag不是1,继续wait,浪费了一次循环。

不知道说清楚没
所以你加了sleep后print_A执行的时候flag肯定已经置为1了!!不加不确定

你可以在打印A的循环体里面添加System.out.println();感受下,的确循环了10次

我把你的代码修改了,你抄一遍体会一下:
图片描述

图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题