多线程如何顺序输出ABC


前言

记录多线程实现ABC

一、原子类加循环判断

package mainin.thread;

import java.util.concurrent.atomic.AtomicInteger;

public class Test1 {

    private static AtomicInteger order = new AtomicInteger(1);
    public static void main(String[] args) {
        
        Thread A = new Thread(()->{
            // 不断循环一直判断
            while (true){
                // order为1的时候进入
                if(order.get()==1){
                    System.out.println("A");
                    order.getAndIncrement();
                    // 输出A 并且跳出死循环,结束本线程
                    break;
                }
            }
        });
        Thread B = new Thread(()->{
            // 不断循环一直判断
            while (true){
                // order为2的时候进入也就是上个线程自增1后进入本线程
                if(order.get()==2){
                    System.out.println("B");
                    order.getAndIncrement();
                    break; //跳出循环
                }
            }
        });
        Thread C = new Thread(()->{
            // 不断循环一直判断
            while (true){
                // order为3的时候进入
                if(order.get()==3){
                    System.out.println("C");
                    order.getAndIncrement();
                    break;//跳出循环
                }
            }
        });
        A.start();
        B.start();
        C.start();
    }

}

多次运行结果如下:
在这里插入图片描述
总结:这种方法是最初级的办法,也是最容易理解的办法,但是对cpu的消耗是很大的,因为一直都在死循环while(true)判断。

二、使用coundownlatch

package mainin.thread;

import java.util.concurrent.CountDownLatch;

public class Test2 {

    public static void main(String[] args) {
        CountDownLatch countDownLatch1 = new CountDownLatch(1);
        CountDownLatch countDownLatch2 = new CountDownLatch(1);
        CountDownLatch countDownLatch3 = new CountDownLatch(1);
        
        Thread A = new Thread(()->{
            try {
                // 本线程阻塞,在线程外 countdown
                countDownLatch1.await();
                System.out.println("A");
                //释放B线程
                countDownLatch2.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {

            }

        });
        Thread B = new Thread(()->{
            try {
                // 本线程阻塞
                countDownLatch2.await();
                System.out.println("B");
                //释放最后一个线程
                countDownLatch3.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {

            }

        });
        Thread C = new Thread(()->{
            try {
                // C线程阻塞
                countDownLatch3.await();
                System.out.println("C");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {

            }

        });
        A.start();
        B.start();
        C.start();
        //开始释放第一个线程
        countDownLatch1.countDown();
    }
}

多次执行结果如下:
在这里插入图片描述

三、使用thread.join方式

package mainin.thread;

public class Test3 {

    public static void main(String[] args) {
        ThreadA A= new ThreadA();
        ThreadB B = new ThreadB();
        ThreadC C = new ThreadC();
        B.setA(A);
        C.setB(B);
        // C执行前--》B B执行前---》A
        //这样无论是从哪个线程开始,都能依次去找上一个执行的线程,就可以达到顺序执行的目的。
        A.start();
        B.start();
        C.start();
    }

    static class ThreadA extends Thread{
        @Override
        public void run() {
            System.out.println("A");
        }
    }

    static class ThreadB extends Thread{
       private ThreadA a;
        @Override
        public void run() {
            try {
                // B执行前把A加入进来,先把A执行了
                a.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B");
        }

        public void setA(ThreadA a) {
            this.a = a;
        }
    }

    static class ThreadC extends Thread{
        private ThreadB b;
        @Override
        public void run() {
            try {
                // C执行前把B加入进来,先把B执行了
                b.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("C");
        }

        public void setB(ThreadB b) {
            this.b = b;
        }
    }
}

多次执行结果如图:
在这里插入图片描述

四、completeFuture方式执行

package mainin.thread;

import com.sun.xml.internal.ws.util.CompletedFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;

public class Test4 {

    public static void main(String[] args) {
        CompletableFuture cf = CompletableFuture.runAsync(() -> {
            System.out.println("A");
        });
        CompletableFuture b = cf.thenApply((C) -> {
            System.out.println("B");
            return null;
        });
        CompletableFuture c = b.thenApply((C) -> {
            System.out.println("C");
            return null;
        });
    }
}

多次运行结果如图:
在这里插入图片描述

五 使用condition实现

package mainin.thread;

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

public class Test5 {
    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition1 = reentrantLock.newCondition();
        Condition condition2 = reentrantLock.newCondition();
        Condition condition3 = reentrantLock.newCondition();
        Thread A = new Thread(()->{
            reentrantLock.lock();
            try {
                //当前线程1等待 由主线程也就main函数线程唤醒
                condition1.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("A");
            //唤醒下一个线程
            condition2.notify();
            reentrantLock.unlock();
        });

        Thread B = new Thread(()->{
            reentrantLock.lock();
            try {
                //线程B等待,等待线程A唤醒
                condition2.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B");
            //唤醒线程C
            condition3.notify();
            reentrantLock.unlock();
        });

        Thread C = new Thread(()->{
            
            reentrantLock.lock();
            try {
                // 当前线程等待
                condition3.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("C");
            reentrantLock.unlock();
        });
        A.start();
        B.start();
        C.start();
        condition1.notify();

    }
}

多次执行后结果截图:
在这里插入图片描述

总结

1.使用了五种方式进行这个简单功能的实现,进一步增强对于多线程相关类的理解。
2.其中condition和countdownlatch的实现方式思想是类似的,
3.其实如果不是为了练习多线程,其实最简单的直接一个线程三个systemout就完了,这个是最简单的办法,也就是串行就完了,所以实际意义上的使用不会这样子实现的,也就是为了练习而已。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值