zoukankan      html  css  js  c++  java
  • Java之【线程通信】--标志位练习

    * 写两个线程,一个线程打印1-52,另一个线程答应字母A-Z。
    * 打印顺序为12A34B56C……5152Z。通过使用线程之间的通信协调关系。

    • 注:分别给两个对象构造一个对象o,数字每打印两个或字母每打印一个就执行o.wait()。
    • 在o.wait()之前不要忘了写o.notify()

    代码:

    方法一:直接写

    package Homework;
    
    public class Test2 {
        public static void main(String[] args) {
            O o=new O();
            Threadnum threadnum=new Threadnum(o);
            Threadabc threadabc=new Threadabc(o);
            Thread thread=new Thread(threadnum);
            Thread thread2=new Thread(threadabc);
            thread.start();
            thread2.start();
        }
    }
    
    //资源类线程O
    class O{
        public synchronized void num(){
            /*for(int i=1;i<=52;i++){
                System.out.print(i);
                if (i % 2 == 0) {
                    this.notify();
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO 待完善
                        e.printStackTrace();
                    }
                }*/
            for(int i=0;i<26;i++){  
                this.notify();
                for(int j=1+2*i;j<2*i+3;j++){
                    System.out.print(j);
                }
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
        public synchronized void abc(){
            for(int i=65;i<91;i++){
                this.notify();
                System.out.print((char)(i));
                //终止程序,执行完最后一次,不需要在等待了
                if(i<90){
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    //打印数字线程
    class Threadnum implements Runnable{
        O o;
        public Threadnum(O o){
            this.o=o;
        }
        @Override
        public void run() {
            o.num();
        }
    }
    
    //打印字母线程
    class Threadabc implements Runnable{
        O o;
        public Threadabc(O o){
            this.o=o;
        }
        @Override
        public void run() {
            try {
                Thread.sleep(20);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            o.abc();
        }
    }

    运行结果:
    这里写图片描述

    方法二:采用标志位

    资源类:

    package com.qf.demo2;
    // 12A34B56C
    /**
     *  线程间通信  需要放在线程同步中
     * 1 资源类中方法  是同步的
     * 2  boolean标志   标志状态
     * 3  方法里面 先判断状态(是否需要等待)
     * 4  如果不需要等待 执行 打印 加减操作
     * 5  执行完操作以后需要切换状态
     * 6  唤醒对象线程 
     *
     */
    public class Resource {
    
        boolean flag = true;  // true  打印了字母还没有打印数字      字母等着  数字打印
                              // false  打印了数字了 还没有打印字母     数字等着  字母打印
    
        // 先打印两个数字
        public synchronized void printNum(int num){
            if(flag==false){// 打印了数字  还没打印字母
                try {
                    this.wait();// 数字等着
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //  true 打印了字母 还没打印数字    打印数字
            System.out.print(num+""+(num+1));// 1   12  34
            //已经打印完了数字了    切换状态
            flag = false;
            //唤醒字母线程
            this.notify();
    
        }
        // 在打印一个字母
        public synchronized void printLetter(int letter){
            if(flag == true){//打印了字母还没有打印数字   
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            // false  打印了数字还没打印字母   打印字母
            System.out.print((char)(letter+65));
            // 打印完了字母了 ,需要切换状态
            //切换成  打印完了字母,还没打印数字  true
            flag = true;
            // 唤醒对方线程
            this.notify();
        }
    }
    

    测试类:

    package com.qf.demo2;
    
    public class Test {
    
        public static void main(String[] args) {
            Resource resource = new Resource();
    
            Number number = new Number(resource);
            Letter letter = new Letter(resource);
    
            Thread thread = new Thread(number);
            Thread thread2 = new Thread(letter);
    
            thread.start();
            thread2.start();
        }
    }
    
    class Number implements Runnable{
        Resource resource ;
        public Number(Resource resource) {
            this.resource = resource;
        }
        @Override
        public void run() {
            for (int i = 1; i < 52; i+=2) {
                // 1  3   5  7  9 
                resource.printNum(i);
            }
    
        }
    }
    
    class Letter implements Runnable{
        Resource resource ;
        public Letter(Resource resource) {
            this.resource = resource;
        }
        @Override
        public void run() {
            for (int i = 0; i < 26; i++) {
                resource.printLetter(i);
            }
    
        }
    }
  • 相关阅读:
    【总结】st表
    【luogu】p2024 食物链
    【总结】stl(以后还会慢慢补上
    【总结】二叉堆
    【luogu】p1631 序列合并
    才子们博客地址
    Lemon测评软件使用说明 (对比cena)
    Cena编译器的使用 及任大佬和禚大佬解释(O2优化、C++11特性、开栈)值得大家学习
    编程求100内的素数
    【关于德育和道德方面】
  • 原文地址:https://www.cnblogs.com/TCB-Java/p/6797616.html
Copyright © 2011-2022 走看看