循环打印ABC10次

一、题目

有A、B、C 三个线程,A线程 输出“A”,B线程 输出“B”,C线程 输出“C”,要求同时启动3个线程,按照顺序输出“ABC”,循环10次,请使用代码实现。

二、问题分析

  1. A、B、C 三个线程;这表示我们要使用多线程同步,有人说了这不废话吗。是的,笔者只是想说,多线程的实现,有几种方式,①继承Thread,②实现Runnable 接口、③实现Cannable接口
  2. A线程 输出“A”,B线程 输出“B”,C线程 输出“C”:这意味着,3个线程之间的执行体run()不同,要想打印的字符串不同有两种方式;
    1. 采用静态方式,直接打印
      1. 这种方式,显然,需要3个不同的执行体,也就意味着,我们要实现三个不同的线程类,即3个Class
    2. 采用构造器参数动态传递方式,将要打印ABC 分别作为参数变量传递进来打印
      1. 这种方式,只需要1个共同的执行体,也就是只需要实现一个线程类,即1个Class。
  3. 按照顺序输出“ABC”:这表示,我们要控制线程的顺序,控制线程的顺序有哪些?
    1. 采用共享标识 ,对循环的序号进行控制,如:循环总数 %3 的余数,来指定应该对应的哪一个线程
    2. 采用互斥锁 :①synchronized和Obejct的wait()、notify,②ReentrantLock和Condition类await 、signal
    3. 采用原子类型变量 :如,AtomicInteger
  4. 循环打印10次:这说明,我们需要定义一个线程共享变量static int currentCount,这里不用volatile,是因为volatile,声明变量值的一致性;static声明变量的唯一性。这里需要的是循环打印,是有序的,所以该使用static才对

三、实现

3.1 synchornized

public class CyclePrint002 {
    public static void main(String[] args) {
        new MyThread(0,"A").start();
        new MyThread(1,"B").start();
        new MyThread(2,"C").start();
    }

    //动态变量来控制打印内容
    static class MyThread extends Thread{
        //共享变量,控制打印总次数
        private static Integer curCount=0;
        //加锁对象
        private static Object obj = new Object();
        //要打印的值
        private String val;
        //是否打印标志位 0-A,1-B,2-C
        private Integer flag;
        MyThread(int flag,String val){
            this.flag = flag;
            this.val = val;
        }

        @Override
        public void run(){
            for (int i = 0; i < 10; i++) {
                System.out.println("这是线程"+val+"的第"+i+"次");
                synchronized (obj){
                    System.out.println("这是线程"+val+"的第"+i+"次获取到锁");
                    while(curCount%3 != flag){
                        try{
//                            System.out.println("这是线程"+val+"的第"+i+"次获取到锁后进入等待了");
                            obj.wait();
//                            System.out.println("这是线程"+val+"的第"+i+"次获取到锁后进入等待了然后继续执行了");
                        }
                        catch (InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                    System.out.println(val);
                    curCount++;
                    obj.notifyAll(); // 调用notifyAll方法
                }
            }
        }
    }
}

3.2 ReentrantLock

static class MyThreadLock extends Thread{
        static ReentrantLock lock = new ReentrantLock();
        private static int curCount=0;
        private int flag;
        private String val;

        MyThreadLock(int flag,String val){
            this.flag=flag;
            this.val=val;
        }

        @Override
        public void run(){
            for (int i = 0; i < 10; ) {
                try{
                    lock.lock();
                    while (curCount%3==flag){
                        System.out.println(val);
                        curCount++;
                        i++;
                    }
                }
                finally {
                    lock.unlock();
                }
            }
        }
    }

3.3 ReentrantLock+一个Condition

public static void main(String[] args) {
        new MyThreadLock(0,"A").start();
        new MyThreadLock(1,"B").start();
        new MyThreadLock(2,"C").start();
    }

    static class MyThreadLock extends Thread{
        static ReentrantLock lock = new ReentrantLock();
        static Condition condition = lock.newCondition();
        private static int curCount=0;
        private int flag;
        private String val;

        MyThreadLock(int flag,String val){
            this.flag=flag;
            this.val=val;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
//                System.out.println(val+"--thread this i--"+i);
//                System.out.println(val+"--thread get lock");
                lock.lock();
//                System.out.println(val+"--thread get lock success");
                try{
                    while(curCount%3 != flag){
//                        System.out.println(val+"--thread await");
                        condition.await();
//                        System.out.println(val+"--thread await over");
                    }
                    System.out.println(val);
                    curCount++;
//                    System.out.println(val+"--thread curCount::"+curCount);
//                    System.out.println(val+"--thread signalAll");
                    condition.signalAll();
//                    System.out.println(val+"--thread signalAll over");
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
                finally {
                    lock.unlock();
//                    System.out.println(val+"--thread unlock over");
                }

//                System.out.println(val+"--thread this end i--"+i);
            }
        }
    }

3.4 ReentrantLock+三个Condition

public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try{
                    lock.lock();
                    conditionA.signal();
                    System.out.println("A");
                    conditionC.await();
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
                finally {
                    lock.unlock();
                }

            }
        },"Thread--A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try{
                    lock.lock();
                    conditionB.signal();
                    System.out.println("B");
                    conditionA.await();
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
                finally {
                    lock.unlock();
                }

            }
        },"Thread--B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try{
                    lock.lock();
                    conditionC.signal();
                    System.out.println("C");
                    conditionB.await();
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
                finally {
                    lock.unlock();
                }

            }
        },"Thread--C").start();

    }

3.5 Semaphore

public static void main(String[] args) {
    //用Semaphore
    Semaphore semaphoreA = new Semaphore(1);
    Semaphore semaphoreB = new Semaphore(0);
    Semaphore semaphoreC = new Semaphore(0);

    new Thread(()->{
        try {
            for (int i = 0; i < 10; i++) {
                semaphoreA.acquire();
                System.out.println("A");
                semaphoreB.release();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    new Thread(()->{
        try {
            for (int i = 0; i < 10; i++) {
                semaphoreB.acquire();
                System.out.println("B");
                semaphoreC.release();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    new Thread(()->{
        try {
            for (int i = 0; i < 10; i++) {
                semaphoreC.acquire();
                System.out.println("C");
                semaphoreA.release();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
}

在这里插入图片描述

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值