返回

多线程打印123:线程同步的魅力

后端

用多线程巧解打印123:线程同步的艺术

简介

在并发编程的世界中,线程同步是一个至关重要的概念,它确保多个线程可以安全高效地共享资源。今天,我们将探索一个经典的面试题——用多线程实现循环打印123,深入剖析线程同步的魅力。

线程同步:协作与协调

线程同步是指多个线程协调和协作,以保证共享资源的安全访问和正确执行。在我们的例子中,三个线程共享了一个打印数字的资源,需要使用线程同步机制防止它们同时访问这个资源,引发冲突。

解决方案:互斥锁的妙用

Java 中提供了多种线程同步机制,其中互斥锁是最简单、最常用的。它允许一个线程一次访问共享资源,而其他线程必须等待,直到该线程释放锁。

基于互斥锁,我们可以设计出以下解决方案:

public class Print123 {
    private static final Object lock = new Object();
    private static int count = 1;

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    while (count != 1) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print("1");
                    count = 2;
                    lock.notifyAll();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    while (count != 2) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print("2");
                    count = 3;
                    lock.notifyAll();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    while (count != 3) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print("3");
                    count = 1;
                    lock.notifyAll();
                }
            }
        }).start();
    }
}

在这个解决方案中,我们使用了一个 Object 类型的锁来同步三个线程的访问。count 变量表示当前要打印的数字,初始值为 1。三个线程轮流获取锁,检查 count 变量的值,如果与自己要打印的数字不一致,则等待其他线程释放锁。当 count 变量的值与自己要打印的数字一致时,则打印数字,并更新 count 变量的值,最后释放锁。

这样,三个线程就可以按照 123 的顺序循环打印数字。

线程同步的意义

线程同步是并发编程中的一块基石,它保障了共享资源的安全性、避免了线程之间的冲突,确保了程序的正确执行。它不仅在打印 123 这样的经典面试题中体现,更在实际应用中发挥着不可或缺的作用。

常见问题解答

1. 为什么使用互斥锁,而不是其他线程同步机制?

互斥锁简单易用,对于这种需要确保独占访问的场景,互斥锁是最合适的。

2. 如何处理线程等待期间的异常?

我们在 wait() 方法中捕获了 InterruptedException 异常,打印异常信息并继续运行。

3. 为什么需要使用 synchronized 代码块?

synchronized 代码块可以确保线程在获取锁之前不会执行,防止了线程在锁可用之前进入临界区。

4. 如何提高打印效率?

可以通过减少线程切换来提高打印效率,例如使用 ThreadLocal 变量存储线程局部信息。

5. 在实际应用中,线程同步还有什么作用?

线程同步广泛应用于并发数据结构、线程池、消息队列等场景,保证了并发执行的正确性和一致性。

结语

通过这个经典的面试题,我们深入理解了线程同步的概念、实现方式和意义。线程同步是并发编程中的一个重要技巧,掌握它将为你的编程生涯添砖加瓦。