[Java] 多线程计数器


多线程计数器

1. 主要功能

  • 请用“等待唤醒”机制编写一个程序,要求:
    • 第一个线程:遍历 1–1000 所有的数字,在遍历过程中,如果发现这个数字能同时被 2,3,5,7 整除,立即 wait() 退出等待,让第二个线程进入;
    • 第二个线程:运行后,将一个计数器 + 1,之后再唤醒等待的线程;
    • 主线程中:休息 2 秒,让两个线程全部执行完毕,打印“计数器”的结果;
  • 注意:第二个线程使用的计数器,要定义在线程外部;

2. Java 实现

public class Test {

    //开关,isCount用于标记统不统计:true就表示要统计,false表示不统计
    static volatile boolean isCount = false;

    static volatile boolean isFinished = false;

    //用于统计能被整除的数字的个数
    static volatile int counter = 0;

    public static void main(String[] args) {
        /*
        请用“等待唤醒”机制编写一个程序,要求:
        第一个线程:遍历1--1000所有的数字,在遍历过程中,如果发现这个数字能同时被
                        2,3,5,7整除,立即wait()退出等待,让第二个线程进入。

        第二个线程:运行后,将一个计数器 + 1,之后再唤醒等待的线程。

        主线程中:休息2秒,让两个线程全部执行完毕,打印“计数器”的结果。

        注意:第二个线程使用的计数器,要定义在线程外部。
         */

        //生产消费设计模式: 开关控制生产和消费交错运行,关键在于定义这个开关
        // 开关切换的机制:遍历的数字能否被2,3,5,7同时整除
        Runnable r1 = () -> {
            for (int i = 1; i < 1001; i++) {
                //能别几个数同时整除,就被被这几个数的最小公倍数整数,2*3*5*7
                synchronized ("") {
                    if (i % (2 * 3 * 5 * 7) == 0) {
                        isCount = true;
                        //发现需要统计,等待统计线程计算
                        try {
                            System.out.println("遍历线程发现整除数i:" + i + ",counter:" + counter + ",icCount:" + isCount);
                            //唤醒统计线程
                            "".notify();
                            //进入等待状态
                            "".wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            synchronized ("") {
                //遍历完毕
                isFinished = true;
                System.out.println("遍历完毕,isFinished:" + isFinished);
                "".notify();//这里还notify的原因是怕统计线程还在wait()
            }
        };

        //int count = 0;//局部变量在匿名内部类中会被当成final修饰

        Runnable r2 = () -> {
            //只要还没遍历结束
            while (!isFinished) {
                synchronized ("") {
                    if (isCount == true) {
                        //统计过程:统计完毕之后,更改开关,进入wait状态
                        counter++;
                        isCount = false;
                        try {
                            System.out.println("统计线程统计,counter:" + counter + ",icCount:" + isCount);
                            //唤醒等待线程
                            "".notify();
                            //进入等待状态
                            "".wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            System.out.println("统计线程结束,isFinished:" + isFinished);
        };

        new Thread(r1).start();
        new Thread(r2).start();

        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(counter);

    }
}
发布了255 篇原创文章 · 获赞 258 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Regino/article/details/104980382