美文网首页
线程交替运行

线程交替运行

作者: 多关心老人 | 来源:发表于2020-07-15 15:00 被阅读0次

问题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

相关文章

  • 线程交替运行

    问题1:4个线程交替打印ABCD方案一:用CyclicBarrir和CountDownLatch, CountDo...

  • 线程间通信实例

    如何让两个线程依次执行? 主线程等待子线程运行 那如何让 两个线程按照指定方式有序交叉运行呢? 多线程交替打印AB...

  • jmeter循环控制器的总结(一)

    1,交替控制器交替控制器下的请求主要和线程组下的请求或者其他控制器下的请求交替运行。例如:@1,我们创建一个线程组...

  • 线程的交互

    题目为:要求:子线程运行执行 10 次后,主线程再运行 5 次。这样交替执行三遍大致思路为,创建一个子线程和mai...

  • redis实现分布式锁

    一、什么是线程安全 当多个线程访问某个类时,不管运行时环境采用何种类,调度方式或者这些线程将如何交替执行,...

  • Java并发编程 线程安全性

    什么是线程安全性 线程安全性:当多个线程访问某个类时,不管运行时采用何种调度方式或者这些线程将被如何交替执行,并且...

  • Java高并发编程学习笔记-(一)

    并发: 同时拥有两个或者多个线程,如果程序在单核处理器上运行,多个线程交替得换入或者换出内存,这些线程是同时“存在...

  • 慕课网高并发实战(一)-并发与高并发基本概念

    并发: 同时拥有两个或者多个线程,如果程序在单核处理器上运行,多个线程交替得换入或者换出内存,这些线程是同时“存在...

  • 慕课网高并发实战(一)-并发与高并发基本概念

    课程网址 并发: 同时拥有两个或者多个线程,如果程序在单核处理器上运行,多个线程交替得换入或者换出内存,这些线程是...

  • 线程安全性

    线程安全: 当多个线程访问某个类(对象)时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代...

网友评论

      本文标题:线程交替运行

      本文链接:https://www.haomeiwen.com/subject/ihwdhktx.html