https://www.cnblogs.com/gustavo

Gustavo's Blog

人类的赞歌是勇气的赞歌!

[Thread] 多线程顺序执行

 

Join

主线程join

启动线程t1,随后调用join,main线程需要等t1线程执行完毕后继续执行。

public class MainJoin {

    static class MyThread implements Runnable {

        String name;

        public MyThread(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name + "开始执行");
            try {
                //todo 业务逻辑
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + "执行完毕");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new MyThread("第一个线程"));
        Thread t2 = new Thread(new MyThread("第二个线程"));
        Thread t3 = new Thread(new MyThread("第三个线程"));
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        t3.start();
    }
}

线程池写法

public class ThreadPool {

    private static final ExecutorService executorService = new ThreadPoolExecutor(1, 1, 0L
            , TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()
            , Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());


    static class MyThread implements Runnable {

        String name;

        public MyThread(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name + "开始执行");
            try {
                //todo 执行业务逻辑
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + "执行完毕");
        }
    }

    public static void main(String[] args) {
        executorService.submit(new MyThread("第一个线程"));
        executorService.submit(new MyThread("第二个线程"));
        executorService.submit(new MyThread("第三个线程"));
        executorService.shutdown();
    }
}

wait notify

这里的原理就是线程t1、t2共用一把锁myLock1,t2先wait阻塞,等待t1执行完毕notify通知t2继续往下执行,线程t2、t3共用一把锁myLock2,t3先wait阻塞,等待t2执行完毕notify通知t3继续往下执行。
image.png

public class WaitNotify {

    private static Object myLock1 = new Object();
    private static Object myLock2 = new Object();

    static class MyThread implements Runnable {

        String name;
        Object startLock;
        Object endLock;

        public MyThread(String name, Object startLock, Object endLock) {
            this.name = name;
            this.startLock = startLock;
            this.endLock = endLock;
        }

        @Override
        public void run() {
            if (startLock != null) {
                synchronized (startLock) {
                    //阻塞
                    try {
                        startLock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            //继续往下执行
            System.out.println(name + "开始执行");
            //todo 执行业务逻辑
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (endLock != null) {
                synchronized (endLock) {
                    //唤醒
                    endLock.notify();
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new MyThread("第一个线程", null, myLock1));
        Thread t2 = new Thread(new MyThread("第二个线程", myLock1, myLock2));
        Thread t3 = new Thread(new MyThread("第三个线程", myLock2, null));
        //打乱顺序执行
        t3.start();
        t1.start();
        t2.start();
    }

}

Condition

类似 wait notify

public class ConditionDemo {

    private static Lock lock = new ReentrantLock();
    private static Condition condition1 = lock.newCondition();
    private static Condition condition2 = lock.newCondition();

    static class MyThread implements Runnable {

        String name;
        Condition startCondition;
        Condition endCondition;

        public MyThread(String name, Condition startCondition, Condition endCondition) {
            this.name = name;
            this.startCondition = startCondition;
            this.endCondition = endCondition;
        }

        @Override
        public void run() {
            //阻塞
            if (startCondition != null) {
                lock.lock();
                try {
                    startCondition.await();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
            //继续往下执行
            System.out.println(name + "开始执行");
            //todo 执行业务逻辑
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //唤醒
            if (endCondition != null) {
                lock.lock();
                try {
                    endCondition.signal();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new MyThread("第一个线程", null, condition1));
        Thread t2 = new Thread(new MyThread("第二个线程", condition1, condition2));
        Thread t3 = new Thread(new MyThread("第三个线程", condition2, null));
        //打乱顺序执行
        t3.start();
        t2.start();
        t1.start();
    }

}

CountDownLatch

public class CountDownLatchDemo {
    static class MyThread implements Runnable {
        CountDownLatch startCountDown;
        CountDownLatch endCountDown;

        public MyThread(CountDownLatch startCountDown, CountDownLatch endCountDown) {
            this.startCountDown = startCountDown;
            this.endCountDown = endCountDown;
        }

        @Override
        public void run() {
            //阻塞
            if (startCountDown != null) {
                try {
                    startCountDown.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //执行自己的业务逻辑
            System.out.println(Thread.currentThread().getName() + "开始执行");
            //todo 执行业务逻辑
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (endCountDown != null) {
                endCountDown.countDown();
            }
        }
    }

    public static void main(String[] args) {
        CountDownLatch countDownLatch1 = new CountDownLatch(1);
        CountDownLatch countDownLatch2 = new CountDownLatch(1);
        Thread t1 = new Thread(new MyThread(null, countDownLatch1), "第一个线程");
        Thread t2 = new Thread(new MyThread(countDownLatch1, countDownLatch2), "第二个线程");
        Thread t3 = new Thread(new MyThread(countDownLatch2, null), "第三个线程");
        //打乱顺序执行
        t3.start();
        t2.start();
        t1.start();
    }
}

等待多线程完成的CountDownLatch
public static void main(String[] args) throws InterruptedException {

    final CountDownLatch latch = new CountDownLatch(5);

    for (int i = 0; i < 5; i++) {

        new Thread(() -> {

            try {

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println("子线程执行");

            latch.countDown();

        }).start();

    }

    latch.await();

    System.out.println("主线程执行");

}

CompletableFutureDemo

public class CompletableFutureDemo {

    static class MyThread implements Runnable {
        @Override
        public void run() {
            System.out.println("执行 : " + Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new MyThread(), "线程1");
        Thread t2 = new Thread(new MyThread(), "线程2");
        Thread t3 = new Thread(new MyThread(), "线程3");
        CompletableFuture.runAsync(t1::start).thenRun(t2::start).thenRun(t3::start);
    }
}

 

posted @ 2022-03-21 09:43  BitBean  阅读(438)  评论(0编辑  收藏  举报