首页 > 其他分享 >【多线程例题】使用三个线程,分别可以打印A,B,C。要求实现三个线程协同打印,顺序打印出ABC。重复10次。【方法一:使用一个锁+一个信号实现根据信号打印】【方法二:使用三个锁,按着顺序解锁打印】

【多线程例题】使用三个线程,分别可以打印A,B,C。要求实现三个线程协同打印,顺序打印出ABC。重复10次。【方法一:使用一个锁+一个信号实现根据信号打印】【方法二:使用三个锁,按着顺序解锁打印】

时间:2024-02-07 11:32:16浏览次数:18  
标签:ABC Thread lock 打印 三个 线程 new

顺序打印-进阶版

方法一:三个线程竞争同一个锁,通过count判断是否打印

在这里插入图片描述 三个线程分别打印A,B,C 方法一:通过count计数打印(三个线程上同样的锁,打印一个,召唤所有锁,如果不满足条件,则wait等待,锁自动解锁) 方法二:

/**
 * 有三个线程,分别只能打印A,B和C
 * 要求按顺序打印ABC,打印10次
 * 输出示例:
 * ABC
 * ABC
 * ABC
 * ABC
 * ABC
 * ABC
 * ABC
 * ABC
 * ABC
 * ABC
 */
public class Thread_ {
    // 计数器
    private static volatile int COUNTER = 0;
    // 定义一个单独的锁对象
    private static Object lock = new Object();

    public static void main(String[] args) {
        // 创建三个线程,并指定线程名,每个线程名分别用A,B,C表示
        Thread t1 = new Thread(() -> {
            // 循环10次
            for (int i = 0; i < 10; i++) {
                // 执行的代码加锁
                synchronized (lock) {
                    // 每次唤醒后都重新判断是否满足条件// 每条线程判断的条件不一样,注意线程t1,t2
                    while (COUNTER % 3 != 0) {
                        try {
                            // 不满足输出条件时,主动等待并释放锁
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 满足输出条件,打印线程名,每条线程打印的内容不同
                    System.out.print(Thread.currentThread().getName());
                    // 累加计数
                    COUNTER++;
                    // 唤醒其他线程
                    lock.notifyAll();
                }
            }
        }, "A");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    while (COUNTER % 3 != 1) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(Thread.currentThread().getName());
                    COUNTER++;
                    lock.notifyAll();
                }
            }
        }, "B");

        Thread t3 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    while (COUNTER % 3 != 2) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    // 换行打印
                    System.out.println(Thread.currentThread().getName());
                    COUNTER++;
                    lock.notifyAll();
                }
            }
        }, "C");

        // 启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

方法二:三个线程同时start,分别上锁,从a开始,打印后唤醒b

public class Demo {
    private static Object locker1 = new Object();
    private static Object locker2 = new Object();
    private static Object locker3 = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker1) {
                        locker1.wait();
                    }
                    System.out.print("A");
                    synchronized (locker2) {
                        locker2.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker2) {
                        locker2.wait();
                    }
                    System.out.print("B");
                    synchronized (locker3) {
                        locker3.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker3) {
                        locker3.wait();
                    }
                    System.out.println("C");
                    synchronized (locker1) {
                        locker1.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        t2.start();
        t3.start();

        Thread.sleep(1000);

        // 从线程 t1 启动
        synchronized (locker1) {
            locker1.notify();
        }
    }
}

方法三:用Condition上锁解锁,可以指定解开哪个锁

class Test {
    public static void main(String[] args) throws InterruptedException {

        Lock lock = new ReentrantLock();
        Condition c1 = lock.newCondition();
        Condition c2 = lock.newCondition();
        Condition c3 = lock.newCondition();

        Thread t1 = new Thread(()->{
            lock.lock();
            for (int i = 1; i <= 10; i++) {
                try {
                    if (i != 1) {
                        c1.await();
                    }
                    System.out.println(Thread.currentThread().getName());
                    c2.signal();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            lock.unlock();
        },"A");

        Thread t2 = new Thread(()->{
            lock.lock();
            for (int i = 1; i <= 10; i++) {
                try {
                    c2.await();
                    System.out.println(Thread.currentThread().getName());
                    c3.signal();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            lock.unlock();
        },"B");

        Thread t3 = new Thread(()->{
            lock.lock();
            for (int i = 1; i <= 10; i++) {
                try {
                    c3.await();
                    System.out.println(Thread.currentThread().getName());
                    c1.signal();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            lock.unlock();
        },"C");

        t3.start();
        t2.start();
        t1.start();
        t1.join();
        t2.join();
        t3.join();

    }
}

标签:ABC,Thread,lock,打印,三个,线程,new
From: https://blog.51cto.com/u_15323027/9635616

相关文章

  • 解锁阿里巴巴面试题:创建线程的几种方式?
    大家好,我是小米!今天我们来聊一个热门话题——阿里巴巴面试题:创建线程的几种方式。在技术的海洋中,线程是我们编程航程中的一艘不可或缺的船,驶向程序的未知领域。那么,究竟有哪些方式可以创建线程呢?让我们一起揭开这个技术的神秘面纱!实现Runnable接口首先,我们来说说最常见、最推荐的方......
  • FolkMQ "单线程"消息中间件 v1.0.32 发布
    简介采用“单线程”+“多路复用”+"内存运行"+"快照持久化"+"Broker集群模式"(可选)基于Socket.D网络应用协议开发。全新设计,自主架构!角色功能生产端发布消息(Qos0、Qos1)、定时消息(Qos0、Qos1)、可过期消息(Qos0、Qos1)消费端订阅、取消订阅消费......
  • Java新建一个子线程异步运行方法
    如何在运行主方法的同时异步运行另一个方法,我是用来更新缓存;1.工具类publicclassThreadPoolUtils{privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(ThreadPoolUtils.class);privatestaticfinalStringPOOL_NAME="thread-im-runner";//......
  • lazarus 3.0/fpc3.3.1写线程要注意的事项
    近日和高勇交流中发现,以下代码在delphi能编译及正确执行。procedureTForm1.Button2Click(Sender:TObject);vari:integer;beginTThread.CreateAnonymousThread(procedurebeginsleep(3000);TThread.Synchronize(TThread.CurrentThread,proced......
  • 打印三角形 (5行)
    需求打印三角形(5行)代码实现packagecom.jichu.struct;publicclassTestDemo{publicstaticvoidmain(String[]args){//打印三角形5行for(inti=1;i<=5;i++){//i行for(intj=5;j>=i;j--){//j一行几个左边第一个......
  • [office] Excel怎么设置从指定部分分页打印
    excel表格中的指定一部分数据想分成两页打印,该怎么设置呢?下面就跟小编一起看看吧。Excel设置从指定部分分页打印的步骤1、现有如下字段:按班级进行打印。一班的同学打印在一张纸上。二班的同学打印在一张纸上!2、点击视图菜单下面的分页预览3、选择要分割的......
  • Qt processEvents - 解决线程中事件阻塞(如槽函数被阻塞)
    百度了一会,发现没太有文字讲这件事情,因此整理成文字记录一下。processEvents介绍长时间运行的操作可以调用processEvents()保持应用程序响应能力。voidQCoreApplication::processEvents(QEventLoop::ProcessEventsFlagsflags=QEventLoop::AllEvents)根据指定的条件为调......
  • java 关于有序获取多线程的返回结果问题,按提交任务的顺序,收集执行结果
    问题:以前做的多线程,执行的返回结果都是无序的,所以每次执行完毕后还要对结果集重新进行排序,增加了耗时; 今天突然想到一个思路,在给线程池提交任务的时候,可以提前获取任务总数,创建一个用于接收结果集的固定大小list2,然后子线程执行的时候把当前任务序号传进去,处理好数据后根据序号......
  • 打印九九乘法表
    需求打印九九乘法表代码实现packagecom.jichu.struct;publicclassForDemo03{publicstaticvoidmain(String[]args){//打印九九乘法表for(inti=1;i<10;i++){//i列for(intj=1;j<=i;j++){//j行int......
  • 深入浅出Java多线程(九):synchronized与锁
    引言大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第九篇内容:synchronized与锁。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!!在现代软件开发中,多线程技术是提升系统性能和并发能力的关键手段之一。Java作为主流的编程语言,其内置的多线程机制为开发者......