0
点赞
收藏
分享

微信扫一扫

线程交替运行

Gascognya 2021-09-21 阅读 95
我的博客

问题1:4个线程交替打印ABCD
方案一:
用CyclicBarrir和CountDownLatch, CountDownLatch起到hold住所有线程的作用,每个线程判断barrier上的waitingNumber来决定是否打印,每个线程都是死循环。

public static void main(String... args) {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        //4个线程交替打印ABCD
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4, () -> {
            logger.info("开始新的一轮打印");
        });

        Thread athread = new Thread(() -> {
            try {
//先暂停住
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("开始执行");
            while (true) {
                try {
                    if (cyclicBarrier.getNumberWaiting() == 0) {
                        logger.info("A");
                        cyclicBarrier.await();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }

        }, "athread");
        Thread bthread = new Thread(() -> {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("开始执行");
            while (true) {
                try {
                    if (cyclicBarrier.getNumberWaiting() == 1) {
                        logger.info("B");
                        cyclicBarrier.await();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }

        }, "bthread");
        Thread cthread = new Thread(() -> {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("开始执行");
            while (true) {
                try {
                    if (cyclicBarrier.getNumberWaiting() == 2) {
                        logger.info("C");
                        cyclicBarrier.await();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }

            }

        }, "cthread");
        Thread dthread = new Thread(() -> {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("开始执行");
            while (true) {
                try {
                    if (cyclicBarrier.getNumberWaiting() == 3) {
                        logger.info("D");
                        cyclicBarrier.await();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }

            }

        }, "dthread");

        athread.start();
        bthread.start();
        cthread.start();
        dthread.start();
        //让子线程全部运行
        countDownLatch.countDown();
        sleep(10000000L);
    }

    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

运行结果:

2020-07-15 14:04:35,508 INFO  [athread] com.x.order.service.NormalTest.lambda$main$1(1577) - A
2020-07-15 14:04:35,508 INFO  [bthread] com.x.order.service.NormalTest.lambda$main$2(1597) - B
2020-07-15 14:04:35,508 INFO  [cthread] com.x.order.service.NormalTest.lambda$main$3(1617) - C
2020-07-15 14:04:35,508 INFO  [dthread] com.x.order.service.NormalTest.lambda$main$4(1638) - D
2020-07-15 14:04:35,508 INFO  [dthread] com.x.order.service.NormalTest.lambda$main$0(1564) - 开始新的一轮打印
2020-07-15 14:04:35,508 INFO  [athread] com.x.order.service.NormalTest.lambda$main$1(1577) - A
2020-07-15 14:04:35,508 INFO  [bthread] com.x.order.service.NormalTest.lambda$main$2(1597) - B
2020-07-15 14:04:35,508 INFO  [cthread] com.x.order.service.NormalTest.lambda$main$3(1617) - C
2020-07-15 14:04:35,508 INFO  [dthread] com.x.order.service.NormalTest.lambda$main$4(1638) - D

这种方式的缺点:4个线程一直在运行,cpu使用率高。

方案二:
用4个Condition,每个后面的线程需要被前一个线程唤醒;刚开始的时候a线程由main线程唤醒。

public static void main(String... args) {
        Lock lock = new ReentrantLock();
        final Condition aCondition = lock.newCondition();
        final Condition bCondition = lock.newCondition();
        final Condition cCondition = lock.newCondition();
        final Condition dCondition = lock.newCondition();

        Thread athread = new Thread(() -> {
            //先停住
            lock.lock();
            try {
                aCondition.await();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }

            while (true) {
                lock.lock();
                try {
                    logger.info("A");
// 通知b线程运行, b线程会尝试获取锁,但是a线程还没把锁释放,b会一直等待
                    bCondition.signalAll();
//a线程释放锁,同事加入aCondition的等待队列。当d线程调用aCondition.signall()的时候,a线程会再次尝试获取锁,然后从下一行代码继续运行
                    aCondition.await();
                    logger.info("新一轮打印开始");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }

        }, "athread");
        Thread bthread = new Thread(() -> {
            lock.lock();
            try {
                bCondition.await();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
            while (true) {
                lock.lock();
                try {
                    logger.info("B");
                    cCondition.signalAll();
                    bCondition.await();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }

        }, "bthread");
        Thread cthread = new Thread(() -> {
            lock.lock();
            try {
                cCondition.await();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
            while (true) {
                lock.lock();
                try {
                    logger.info("C");
                    dCondition.signalAll();
                    cCondition.await();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }

        }, "cthread");
        Thread dthread = new Thread(() -> {
            lock.lock();
            try {
                dCondition.await();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
            while (true) {
                lock.lock();
                try {
                    logger.info("D");
                    aCondition.signalAll();
                    dCondition.await();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }

        }, "dthread");

        athread.start();
        bthread.start();
        cthread.start();
        dthread.start();
        lock.lock();
        try{
            aCondition.signalAll();
        }finally {
            lock.unlock();
        }
        sleep(10000000L);
    }

    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

运行结果:

2020-07-15 14:47:58,411 INFO  [athread] com.x.order.service.NormalTest.lambda$main$0(1581) - A
2020-07-15 14:47:58,411 INFO  [bthread] com.x.order.service.NormalTest.lambda$main$1(1605) - B
2020-07-15 14:47:58,411 INFO  [cthread] com.x.order.service.NormalTest.lambda$main$2(1628) - C
2020-07-15 14:47:58,411 INFO  [dthread] com.x.order.service.NormalTest.lambda$main$3(1652) - D
2020-07-15 14:47:58,411 INFO  [athread] com.x.order.service.NormalTest.lambda$main$0(1584) - 新一轮打印开始
2020-07-15 14:47:58,411 INFO  [athread] com.x.order.service.NormalTest.lambda$main$0(1581) - A
2020-07-15 14:47:58,411 INFO  [bthread] com.x.order.service.NormalTest.lambda$main$1(1605) - B
2020-07-15 14:47:58,411 INFO  [cthread] com.x.order.service.NormalTest.lambda$main$2(1628) - C
2020-07-15 14:47:58,411 INFO  [dthread] com.x.order.service.NormalTest.lambda$main$3(1652) - D
举报

相关推荐

0 条评论