zoukankan      html  css  js  c++  java
  • 笔试题--有3个线程A/B/C,其中A、B个线程轮流打印1-100 中间如果是10的倍数,则由C线程打印;

     * 评测题目: 有3个线程A/B/C,其中A、B个线程轮流打印1-100 中间如果是10的倍数,则由C线程打印;
     * 要求在控制台输入如下内容:
     * 线程A:1
     * 线程B:2
     * 线程A:3
     * ……
     * 线程C:10
     * ……
     * 线程?:100

        /**
         * 多个线程共享这一个sequence数据
         */
        private static int sequence = 1;
    
        private static final int SEQUENCE_END = 100;
    
        private Integer id;
        private ReentrantLock lock;
        private Condition[] conditions;
        private String name = "";
    
    
        private ThreadPrintService() {
    
        }
    
        private ThreadPrintService(String name, Integer id, ReentrantLock lock, Condition[] conditions) {
            this.id = id;
            this.lock = lock;
            this.conditions = conditions;
            this.name = name;
        }
    
        @Override
        public void run() {
            while (sequence >= 0 && sequence <= SEQUENCE_END) {
                lock.lock();
                try {
                    //对序号取模,如果不等于当前线程的id,则先唤醒其他线程,然后当前线程进入等待状态
                    while (sequence % 2 != id) {
                        if (sequence % 10 == 0) {
                            break;
                        }
                        conditions[(id + 1) % conditions.length].signal();
                        conditions[(id + 2) % conditions.length].signal();
                        conditions[id].await();
                    }
                    System.out.println(name + " : " + sequence);
                    //序号加1
                    sequence = sequence + 1;
                    //唤醒当前线程的下一个线程
                    conditions[(id + 2) % conditions.length].signal();
                    //当前线程进入等待状态
                    conditions[id].await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //将释放锁的操作放到finally代码块中,保证锁一定会释放
                    lock.unlock();
                }
            }
            //数字打印完毕,线程结束前唤醒其余的线程,让其他线程也可以结束
            end();
        }
    
        private void end() {
            lock.lock();
            conditions[(id + 1) % conditions.length].signal();
            conditions[(id + 2) % conditions.length].signal();
            lock.unlock();
        }
    
        public void startThread() {
            int threadCount = 3;
            String name = "";
            ReentrantLock lock = new ReentrantLock();
            Condition[] conditions = new Condition[threadCount];
            for (int i = 0; i < threadCount; i++) {
                conditions[i] = lock.newCondition();
            }
            ThreadPrintService[] printNumbers = new ThreadPrintService[threadCount];
            for (int i = 0; i < threadCount; i++) {
                switch (i) {
                    case 0:
                        name = "B";
                        break;
                    case 1:
                        name = "A";
                        break;
                    case 2:
                        name = "C";
                        break;
                }
                ThreadPrintService p = new ThreadPrintService(name, i, lock, conditions);
                printNumbers[i] = p;
            }
            for (ThreadPrintService printNumber : printNumbers) {
                new Thread(printNumber).start();
            }
        }
  • 相关阅读:
    hive数据仓库入门到实战及面试
    clickhouse入门到实战及面试
    透过源码看懂Flink核心框架的执行流程
    hive经典练习题
    flink批处理从0到1学习
    flink基础篇
    flink进阶篇
    flink源码阅读
    spark优化总结
    uni-app跨平台移动应用开发
  • 原文地址:https://www.cnblogs.com/cnndevelop/p/12221259.html
Copyright © 2011-2022 走看看