日常练手--java多线程交替实现打印字母和数字

       为了更加深刻的理解java多线程机制,先从最简单的demo入手实现数字和字母的交叉打印。实现思路是: 首先定义一个对象其中创建三个变量,flag用于控制应该打印字母还是数字,numberPrint输出打印数字,wordPrin用于计算输出的打印字母。然后分别定义一个打印数字的线程和打印字母的线程。最后在主函数中测试即可。

(一)定义两个线程可以访问到的公共资源

public class IsNum {
    boolean flag=true;
    int numberPrint=0;
    int wordPrin=0;
    public IsNum(boolean flag){
        this.flag=flag;
    }
}

(二)定义打印数字的线程

public class PrinNumber extends Thread {
    private IsNum isNum;
    public PrinNumber(String name,IsNum isnum){
        super(name);
        this.isNum=isnum;
    }
    @Override
    public void run(){
        while(isNum.numberPrint<100){
            synchronized (isNum){
                if(isNum.flag) {
                    System.out.println(isNum.numberPrint);
                    isNum.numberPrint++;
                    isNum.flag=false;
                    isNum.notifyAll();
                }else{
                    try{
                        isNum.wait();
                    }catch (InterruptedException e){
                        new RuntimeException(e);

                    }
                }
            }
        }

    }
}

(三)定义打印字母的线程

public class PrintWord extends  Thread{

    private IsNum isNum;
    public PrintWord(String name,IsNum isnum){
        super(name);
        this.isNum=isnum;
    }
    @Override
    public void run(){
       while(isNum.numberPrint<100){
            synchronized (isNum) {
                if(!isNum.flag) {
                    System.out.println((char) (96 + isNum.wordPrin));
                    isNum.wordPrin++;
                    if (isNum.wordPrin == 26) {
                        isNum.wordPrin = 0;
                    }
                    isNum.flag=true;
                    isNum.notifyAll();
                }else{
                    try{
                        isNum.wait();
                    }catch (InterruptedException e){
                        new RuntimeException(e);

                    }
                }
            }
        }

        }


}

(四)测试程序

public static void main(String[] args) {
      IsNum isNum=new IsNum(false);
      new PrintWord("打印字母",isNum).start();
      new PrinNumber("打印数字",isNum).start();


   }

(五)运行效果

Connected to the target VM, address: '127.0.0.1:54262', transport: 'socket'
`
1
a
2
b
3
c

。。。。。。

(六)深入思考升华
  (1) sycronized 线程同步加锁

         sycronized和sycronized(变量)加锁,获得的是成员锁,一次只能有一个线程进入该方法或者该代码块。使用sycronized(this)和sycronized(类名)两种方式加的是对象锁,此时别的线程在类中所有操作都不能进行。

(2)wait()

        在 Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信。线程在运行的时候,如果发现某些条件没有被满足,可以调用wait方法暂停自己的执行,并且放弃已经获得的锁,然后进入等待状态。当该线程被其他线程唤醒并获得锁后,可以沿着之前暂停的地方继续向后执行,而不是再次从同步代码块开始的地方开始执行。

(3)notifyAll()

       当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争。

(4)start() 

线程调用该方法将启动线程

(5)run()

Thread类的run()方法与Runnable接口中的run()方法的功能和作用相同,都用来定义线程对象被调度之后所执行的操作,都是系统自动调用而用户程序不得引用的方法。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值