Skip to content

奇偶数交替打印

题目来源:2024Java 华晨宝马汽车有限公司后端秋招笔试题

小回说过,很喜欢那种通过一点点的努力,然后感受到自己正在慢慢进步的感觉。就像爬山一样,随着跟山顶的距离逐渐拉近,看到的风景也越来越美,内心更是越发欢愉。其实无论离山顶有多远,人总归应该多看些这种风景的。初次接触多线程的题目,别担心慢慢来,仔细分析,找到互斥的关系,解决题目定不在话下

题目描述

请你编写一个 Java 多线程长度,打印 1 到指定的最大数字 maxCount,其中线程 1 负责打印技术,线程 2 负责打印偶数,需要保证两个线程交替打印,并且不能出现重复的数字,请你实现 Solution 类的 printOdd 方法和 printEven 方法,使 printOdd 方法可以打印“线程名 - 当前奇数”,printEven 方法可以打印“线程名 - 当前偶数”

java
class Solution {

    private final int maxCount; // 最大数字

    public Solution(int maxCount) {
        this.maxCount = maxCount;
    }

    // 开启两个线程分别打印奇数和偶数
    public void start() throws InterruptedException {
        // 线程 OddThread 调用 printOdd();
        Thread oddThread = new Thread(() -> {
            try {
                printOdd();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "OddThread");

        // 线程 EvenThread 调用 printEven();
        Thread evenThread = new Thread(() -> {
            try {
                printEven();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "EvenThread");

        // 启动两个线程
        oddThread.start();
        evenThread.start();

        // 等待子线程执行完成
        oddThread.join();
        evenThread.join();
    }

    public void printOdd() throws InterruptedException {

    }

    public void printEven() throws InterruptedException {

    }
}

示例

java
Solution solution = new Solution(10);
solution.start();

上述代码执行后,结果为
    OddThread-1
    EvenThread-2
    OddThread-3
    EvenThread-4
    OddThread-5
    EvenThread-6
    OddThread-7
    EvenThread-8
    OddThread-9
    EvenThread-10

题目解析

这道题目我们可以使用 synchronized 和 notifyAll 和 wait 来控制线程的执行顺序和变量的安全性

首先我们先定义一个共享变量,然后让两个线程都来操作这一个共享变量

我们让 oddThread 线程打印完就释放锁,并且唤醒另一个线程;让 evenThread 线程执行完就释放锁,然后唤醒奇数线程,比较简单

题目解答

Java
class Solution {

    private final int maxCount; // 最大数字

    private int count = 1;

    public Solution(int maxCount) {
        this.maxCount = maxCount;
    }

    public static void main(String[] args) throws InterruptedException {
        new Solution(15).start();
    }

    // 开启两个线程分别打印奇数和偶数
    public void start() throws InterruptedException {
        // 线程 OddThread 调用 printOdd();
        Thread oddThread = new Thread(() -> {
            try {
                printOdd();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "OddThread");

        // 线程 EvenThread 调用 printEven();
        Thread evenThread = new Thread(() -> {
            try {
                printEven();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "EvenThread");

        // 启动两个线程
        oddThread.start();
        evenThread.start();

        // 等待子线程执行完成
        oddThread.join();
        evenThread.join();
    }

    public void printOdd() throws InterruptedException {

        while (count <= maxCount) {
            synchronized (this) {
                if (count % 2 != 0) {
                    System.out.println(Thread.currentThread().getName() + "-" + count);
                    count++;
                    this.notifyAll();

                } else {
                    this.wait();
                }
            }
        }

    }

    public void printEven() throws InterruptedException {
        while (count <= maxCount) {
            synchronized (this) {
                if (count % 2 == 0) {
                    System.out.println(Thread.currentThread().getName() + "-" + count);
                    count++;
                    this.notifyAll();
                } else {

                    this.wait();
                }
            }
        }
    }
}

当 maxCount=6 的时候执行结果如下,符合我们的要求

java
OddThread-1
EvenThread-2
OddThread-3
EvenThread-4
OddThread-5
EvenThread-6
本站访客数 人次 本站总访问量