zoukankan      html  css  js  c++  java
  • 面试题 多线程并发 两个线程交替打印 三个线程交替打印

     两个线程交替打印

    public class Test2 {
        private static int count = 0;
        private final static Object lock = new Object();
        static class TurningRunner implements Runnable {
            @Override
            public void run() {
                while (count <= 10) {
                    // 获取锁
                    synchronized (lock) {
                        // 拿到锁就打印
                        System.out.println(Thread.currentThread().getName() + ":" + count++);
                        // 唤醒其他线程
                        lock.notifyAll();
                        try {
                            // 如果任务还没有结束,则让出当前的锁并休眠
                            if (count <= 10) {
                                lock.wait();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread a = new Thread(new TurningRunner(), "偶数");
            Thread b = new Thread(new TurningRunner(), "奇数");
            a.start();
            b.start();
        }
    }

     三个线程交替打印

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    public class PrintNumber extends Thread {
    /**
    * 多个线程共享这一个sequence数据
    */
    private static int sequence = 1;
    private static final int SEQUENCE_END =75;

    private int id;
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition[] conditions = {lock.newCondition(),lock.newCondition(),lock.newCondition()};

    private PrintNumber(int id) {
    this.id = id;
    this.setName("线程:" + (id + 1));
    }

    @Override
    public void run() {
    while (sequence < SEQUENCE_END) {
    lock.lock();
    try {
    //对序号取模,如果不等于当前线程的id,则先唤醒其他线程,然后当前线程进入等待状态
    while ((sequence/5) % conditions.length != id) {
    conditions[(id + 1) % conditions.length].signal();
    conditions[id].await();
    }
    for(int i = 0; i < 5; i++)
    {
    System.out.println(Thread.currentThread().getName() + " " + sequence++);
    }
    //唤醒当前线程的下一个线程
    conditions[(id + 1) % 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 static void main(String[] args) {
    int threadCount = 3;
    // ReentrantLock lock = new ReentrantLock();
    // Condition[] conditions = new Condition[threadCount];
    // for (int i = 0; i < threadCount; i++) {
    // conditions[i] = lock.newCondition();
    // }
    PrintNumber[] printNumbers = new PrintNumber[threadCount];
    for (int i = 0; i < threadCount; i++) {
    printNumbers[i] = new PrintNumber(i);
    }
    for (PrintNumber printNumber : printNumbers) {
    printNumber.start();
    }
    }

    }
  • 相关阅读:
    区别是否是 微信浏览器 ?
    添加收藏
    函数调用那点事
    移动端返回上一页,刚需!document.referrer 详解
    蓝桥杯-乘积尾零
    printf不能直接输出string类型
    bitset的简单用法
    to_string()函数(C++)
    蓝桥杯-明码
    手写C语言字符库
  • 原文地址:https://www.cnblogs.com/yanhowever/p/12336744.html
Copyright © 2011-2022 走看看