笔试题--有3个线程A/B/C,其中AB个线程轮流打印1-100 中间如果是10的倍数,则由C线程打印;

Posted cnndevelop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了笔试题--有3个线程A/B/C,其中AB个线程轮流打印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();
        }
    }

以上是关于笔试题--有3个线程A/B/C,其中AB个线程轮流打印1-100 中间如果是10的倍数,则由C线程打印;的主要内容,如果未能解决你的问题,请参考以下文章

从网易的一道多线程笔试题学习wait与notify来控制线程同步

经典笔试题:线程通信(使用Volatile实现线程间通信)

经典笔试题:线程通信(使用CountDownLatch实现线程间通信)

经典笔试题:线程通信(使用wait,notify实现线程间通信)

经典笔试题:线程通信(使用重入锁(ReentrantLock)和条件队列(Condition)实现线程间通信)

记录一次回客科技有关线程的笔试题,三个线程加法和一个线程减法 ,延申的两个线程交替执行