前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >9.线程按序交替

9.线程按序交替

作者头像
Devops海洋的渔夫
发布2022-03-23 16:23:55
1910
发布2022-03-23 16:23:55
举报
文章被收录于专栏:Devops专栏Devops专栏

9.线程按序交替

线程按序交替

代码语言:javascript
复制
- 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
如:ABCABCABC…… 依次递归

解决的思路

在上一章节中,我们学习了 锁 Lock 以及对应的 condition 线程通讯的控制。那么通过一个锁 Lock 可以创建多个 condition ,例如:

  • 线程1 使用 condition1 来控制阻塞、唤醒
  • 线程2 使用 condition2 来控制阻塞、唤醒
  • 线程3 使用 condition3 来控制阻塞、唤醒

然后我们只要在实现线程类的时候,做好阻塞和唤醒的次序即可。如下:

  • 如果当前是线程1,则 调用 condition1.await() 阻塞 线程1,然后调用 condition2.signal() 唤醒 线程2
  • 如果当前是线程2,则 调用 condition2.await() 阻塞 线程2,然后调用 condition3.signal() 唤醒 线程3
  • 如果当前是线程3,则 调用 condition3.await() 阻塞 线程3,然后调用 condition1.signal() 唤醒 线程1

好了,下面来实现一下代码。

实现代码

代码语言:javascript
复制
import jdk.nashorn.internal.ir.CallNode;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,
 * 每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
 * <p>
 * 如:ABCABCABC…… 依次递归
 *
 * @author Aron.li
 * @date 2020/11/3 23:02
 */
public class TestABCAlternate {

    public static void main(String[] args) {
        AlternateDemo ad = new AlternateDemo();

        //创建线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    ad.runThreadA();
                }
            }
        }, "A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    ad.runThreadB();
                }
            }
        }, "B").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    ad.runThreadC();
                }
            }
        }, "C").start();

    }

}

class AlternateDemo {

    //成员属性
    private int number = 1; //标记当前执行的线程

    //创建lock
    private ReentrantLock lock = new ReentrantLock();
    //创建三个线程的 Condition
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    //设置后续线程中,执行的方法
    public void runThreadA() {
        //如果当前是线程1,则 调用 condition1.await() 阻塞 线程1,
        // 然后调用 condition2.signal() 唤醒 线程2

        lock.lock();//创建锁

        try {
            //1.判断当前不为线程1,则阻塞线程1
            if (number != 1) {
                condition1.await();
            }
            //2.打印A
            System.out.print(Thread.currentThread().getName());
            //3.唤醒线程2
            number = 2;
            condition2.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 释放锁
        }

    }

    public void runThreadB() {
        //如果当前是线程2,则 调用 condition2.await() 阻塞 线程2,
        // 然后调用 condition3.signal() 唤醒 线程3
        lock.lock();//创建锁
        try {
            //1.判断当前不为线程2,则阻塞线程2
            if (number != 2) {
                condition2.await();
            }
            //2.打印B
            System.out.print(Thread.currentThread().getName());
            //3.唤醒线程3
            number = 3;
            condition3.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 释放锁
        }
    }

    public void runThreadC() {
        //如果当前是线程3,则 调用 condition3.await() 阻塞 线程3,
        // 然后调用 condition1.signal() 唤醒 线程1
        lock.lock();//创建锁
        try {
            //1.判断当前不为线程3,则阻塞线程3
            if (number != 3) {
                condition3.await();
            }
            //2.打印C
            System.out.print(Thread.currentThread().getName());
            //3.唤醒线程1
            number = 1;
            condition1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 释放锁
        }
    }

}

执行效果如下:

image-20201103233658677

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 9.线程按序交替
    • 线程按序交替
      • 解决的思路
        • 实现代码
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档