一个有趣的编程题实战----交替打印线程

题目:

有两个线程t1和t2,t1打印123,t2打印ABC,现在需要实现两个线程交替打印为"1A2B3C"

关于这道题我们可以提供多种思路来实现交替打印的结果,例如wait-notify、lock-condition ,以及Semaphore 以及yeild

先使用wait-notify

java 复制代码
public class PrintingWithWaitNotify {
    private static final Object lock = new Object();
    private static boolean printNumber = true;

    public static void main(String[] args) {
        Thread numberThread = new Thread(new NumberPrinter());
        Thread letterThread = new Thread(new LetterPrinter());

        numberThread.start();
        letterThread.start();
    }

    static class NumberPrinter implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                try {
                    for (int i = 1; i <= 3; i++) {
                        while (!printNumber) {
                            lock.wait();
                        }
                        System.out.print(i);
                        printNumber = false;
                        lock.notify();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class LetterPrinter implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                try {
                    for (char c = 'A'; c <= 'C'; c++) {
                        while (printNumber) {
                            lock.wait();
                        }
                        System.out.print(c);
                        printNumber = true;
                        lock.notify();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

使用lock-condition

java 复制代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class PrintingWithReentrant {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        Thread thread1 = new Thread(new PrintNumbers(lock, condition));
        Thread thread2 = new Thread(new PrintLetters(lock, condition));

        thread1.start();
        thread2.start();
    }
}

class PrintNumbers implements Runnable {
    private Lock lock;
    private Condition condition;

    public PrintNumbers(Lock lock, Condition condition) {
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 3; i++) {
            lock.lock();
            try {
                System.out.print(i);
                condition.signal(); // 唤醒打印字母的线程
                if (i < 3) {
                    condition.await(); // 等待打印字母的线程执行
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
            }
        }
    }
}

class PrintLetters implements Runnable {
    private Lock lock;
    private Condition condition;

    public PrintLetters(Lock lock, Condition condition) {
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        for (char letter = 'A'; letter <= 'C'; letter++) {
            lock.lock();
            try {
                System.out.print(letter);
                condition.signal(); // 唤醒打印数字的线程
                if (letter < 'C') {
                    condition.await(); // 等待打印数字的线程执行
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
            }
        }
    }
}

使用 Semaphore

java 复制代码
import java.util.concurrent.Semaphore;

public class PrintingWithSemaphore {
    private static final Semaphore semaphoreNumber = new Semaphore(1);
    private static final Semaphore semaphoreLetter = new Semaphore(0);

    public static void main(String[] args) {
        Thread numberThread = new Thread(new NumberPrinter());
        Thread letterThread = new Thread(new LetterPrinter());

        numberThread.start();
        letterThread.start();
    }

    static class NumberPrinter implements Runnable {
        @Override
        public void run() {
            try {
                for (int i = 1; i <= 3; i++) {
                    semaphoreNumber.acquire();
                    System.out.print(i);
                    semaphoreLetter.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class LetterPrinter implements Runnable {
        @Override
        public void run() {
            try {
                for (char c = 'A'; c <= 'C'; c++) {
                    semaphoreLetter.acquire();
                    System.out.print(c);
                    semaphoreNumber.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

使用yeild

java 复制代码
public class PrintingWithYeild {
    private static volatile boolean printNumber = true;

    public static void main(String[] args) {
        Thread numberThread = new Thread(new NumberPrinter());
        Thread letterThread = new Thread(new LetterPrinter());

        numberThread.start();
        letterThread.start();
    }

    static class NumberPrinter implements Runnable {
        @Override
        public void run() {
            for (int i = 1; i <= 3; i++) {
                while (!printNumber) {
                    Thread.yield();
                }
                System.out.print(i);
                printNumber = false;
                Thread.yield();
            }
        }
    }

    static class LetterPrinter implements Runnable {
        @Override
        public void run() {
            for (char c = 'A'; c <= 'C'; c++) {
                while (printNumber) {
                    Thread.yield();
                }
                System.out.print(c);
                printNumber = true;
                Thread.yield();
            }
        }
    }
}
相关推荐
独断万古他化1 分钟前
【Spring 原理】Bean 的作用域与生命周期
java·后端·spring
m0_694845573 分钟前
tinylisp 是什么?超轻量 Lisp 解释器编译与运行教程
服务器·开发语言·云计算·github·lisp
*小海豚*7 分钟前
在linux服务器上DNS正常,但是java应用调用第三方解析域名报错
java·linux·服务器
春日见8 分钟前
如何创建一个PR
运维·开发语言·windows·git·docker·容器
C++ 老炮儿的技术栈11 分钟前
VS2015 + Qt 实现图形化Hello World(详细步骤)
c语言·开发语言·c++·windows·qt
派葛穆18 分钟前
Python-批量安装依赖
开发语言·python
撩得Android一次心动22 分钟前
Android LiveData 全面解析:使用Java构建响应式UI【源码篇】
android·java·android jetpack·livedata
组合缺一26 分钟前
Solon AI (Java) v3.9 正式发布:全能 Skill 爆发,Agent 协作更专业!仍然支持 java8!
java·人工智能·ai·llm·agent·solon·mcp
MSTcheng.30 分钟前
【C++】C++11新特性(二)
java·开发语言·c++·c++11
晓131333 分钟前
第七章 【C语言篇:文件】 文件全面解析
linux·c语言·开发语言