面试题:使用三个线程,一个线程打印 X,一个线程打印 Y,一个线程打印 Z,按顺序打印X,Y,Z,连续打印10次XYZ

面试题:抛砖引玉

方式1:

package com.shuchang;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 本题目主要考察线程间通信问题:
 * 题目描述:使用三个线程,一个线程打印 X,一个线程打印 Y,一个线程打印 Z,按顺序打印X,Y,Z,连续打印10次XYZ。
 *
 * @Author wsc
 * 2021-09-13 21:23
 **/
public class PrintXYZ1 {
    //定义一把lock锁对象
    static Lock lock = new ReentrantLock();

    //使用lock锁获取三个Condition条件
    static Condition con1 = lock.newCondition();
    static Condition con2 = lock.newCondition();
    static Condition con3 = lock.newCondition();

    // 线程执行标记
    static int flag = 1;

    public static void printX() throws InterruptedException {
        lock.lock();
        while (flag != 1) {
            con1.await();
        }
        flag = 2;
        System.out.print("X");
        con2.signal();
        lock.unlock();
    }

    public static void printY() throws InterruptedException {
        lock.lock();
        while (flag != 2) {
            con2.await();
        }
        flag = 3;
        System.out.print("Y");
        con3.signal();
        lock.unlock();
    }

    public static void printZ() throws InterruptedException {
        lock.lock();
        while (flag != 3) {
            con3.await();
        }
        flag = 1;
        System.out.println("Z");
        con1.signal();
        lock.unlock();
    }

    public static void main(String[] args) {
        //X线程
        Thread x = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        printX();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //Y线程
        Thread y = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        printY();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //Z线程
        Thread z = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        printZ();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        x.start();
        y.start();
        z.start();
    }
}

方式2:

package com.shuchang;

import java.util.concurrent.CountDownLatch;

/**
 * 本题目主要考察线程间通信问题:
 * 题目描述:使用三个线程,一个线程打印 X,一个线程打印 Y,一个线程打印 Z,按顺序打印X,Y,Z,连续打印10次XYZ。
 * @Author wsc
 * 2021-09-13 21:23
 **/
public class PrintXYZ2 {
    //定义CountDownLatch,起到线程通知的作用
    private static CountDownLatch cdl1 = new CountDownLatch(1);
    private static CountDownLatch cdl2 = new CountDownLatch(1);
    private static CountDownLatch cdl3 = new CountDownLatch(1);

    public static void main(String[] args) {
        Thread x = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    //线程启动之后等待,直到con1的门闩变为0
                    cdl1.await();
                    System.out.print("X");
                    //将cdl2的门闩减为0,使cdl2可以从等待返回
                    cdl2.countDown();
                    //新建一个CountDownLatch用于下一次循环
                    cdl1 = new CountDownLatch(1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"printX");

        Thread y = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    cdl2.await();
                    System.out.print("Y");
                    cdl3.countDown();
                    cdl2 = new CountDownLatch(1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"printY");

        Thread z = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    cdl3.await();
                    System.out.println("Z");
                    cdl1.countDown();
                    cdl3 = new CountDownLatch(1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"printZ");
        x.start();
        y.start();
        z.start();
        //三个线程启动完都会等待各自的门闩
        //cdl1门闩先减为0,意味着线程printX会先从等待中返回,从而先打印X
        cdl1.countDown();
    }
}

打印结果:

D:\Tools\jdk1.8.0_231\bin\java.exe ...
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ

Process finished with exit code 0
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值