写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z。(《疯狂java讲义》第12章课后题一)

  1. Print类提供打印两个数字和一个字母的同步方法,这样就能通过Print对象的同步锁机制保证输出数字和字母的顺序符合要求。
public class Print {
    private boolean flag = false;
    private int number = 1;
    private char c = 'A';
    synchronized public boolean numberPrint() throws Exception{
    boolean b = false;
    if(!flag){       
       for(int i = 0; i < 2; i++){
        System.out.print(number++);
       }
       // 用来判断并返回给线程执行体是否输出结束了。
       if(number == 53){     
           b = true;
       }
       else{
           b = false;
       }
        flag = true;
        notifyAll();
    }
    else{
        wait();
    }
    return b;
    }

    synchronized public boolean charPrint() throws Exception{
    boolean b = false;
    if(flag){
        System.out.print(c++);
        // 用来判断并返回给线程执行体是否输出结束了。
        if(c == 'Z' + 1){
        b = true;
        }
        else{
        b = false;
        }
        flag = false;
        notifyAll();
    }
    else{
        wait();
    }
    return b;

    }
}
  1. 创建两个线程类,分别负责输出数字和字母
    输出数字:
public class NumberThread extends Thread {
    private Print print;
    public NumberThread(Print print, String name){
    super(name);
    this.print = print;
    }
    public void run(){
    try{
        boolean b = false;
        /* 这里一开始用的是for循环26次,发现结果输出到2526M就没了,而且进入阻塞状       态。后改为52,倒是全都输出了,可还是阻塞。*/
        /*之所以会这样,是因为你无法确切的知道执行每几次numberPrint()方法才输出1个数字,可能是1次,可能是两次。因为,每次进入numberPrint()后,都要根据旗标flag判断是输出还是等待,有可能,系统线程分配的很好,每次进入时,flag都是输出,也有可能会连续进去两次,一次输出,第二次wait(),所以就无法知道应该执行多少次才符合要求,所以要用while(b)*/
        while(!b){
        b = print.numberPrint();
        }
    }
    catch(Exception e){
        e.printStackTrace();
    }
    }
}


输出字母:

public class CharThread extends Thread {
    private Print print;
    public CharThread(Print print, String name){
    super(name);
    this.print = print;
    }

    public void run(){
    try{
        boolean b = false;
        while(!b){
        b = print.charPrint();
        }
    }
    catch(Exception e){
        e.printStackTrace();
    }
    }
}

主类:

public class TestPrint {

    public static void main(String[] args) {
    Print print = new Print();
    new NumberThread(print, "number").start();
    new CharThread(print, "char").start();
    }

}

所以疯狂java讲义上的那个例子,解释的是不清楚的,for循环100次取钱操作不代表每次都能取出钱,可能实际上只有50次取钱时成功的,也有可能是50到100之间的某个数。
运行结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值