zoukankan      html  css  js  c++  java
  • Java多线程系列四——控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现

    • Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕
    • CountDownLatch类:指定计数器,当计数器清零即取消阻塞
    import java.util.concurrent.CountDownLatch;
    
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
     * @Description: 规定线程次序的方法
     */
    public class ThreadOrderTest {
        private long millisUnit = 1000;
        private int count = 2;
    
        class ThreadOrder {
            /**
             * join方法使多个线程依次执行
             * 
             * @return
             * @throws InterruptedException
             */
            public long preserveOrderViaJoin() throws InterruptedException {
                long startMillis = System.currentTimeMillis();
                Thread tmp;
                for (int i = 0; i < count; i++) {
                    tmp = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(millisUnit);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }, "join-" + i);
                    tmp.start();
                    tmp.join();// 不停地检测线程是否执行完成,执行完成才继续往下
                }
                return System.currentTimeMillis() - startMillis;
            }
    
            /**
             * CountdownLatch可同时阻塞多个线程,但它们可并发执行
             * 
             * @return
             * @throws InterruptedException
             */
            public long preserveOrderViaCountdownLatch() throws InterruptedException {
                long startMillis = System.currentTimeMillis();
                final CountDownLatch countDownLatch = new CountDownLatch(count);
                for (int i = 0; i < count; i++) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(millisUnit);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            countDownLatch.countDown();// 只要计数器清零,等待的线程就可以开始执行,于是可以达到并发的效果
                        }
                    }, "countDownLatch-" + i).start();
                }
                countDownLatch.await();
                return System.currentTimeMillis() - startMillis;
            }
        }
    
        @Test
        public void testPreserveOrderViaJoin() throws InterruptedException {
            ThreadOrder threadOrder = new ThreadOrder();
            Assert.assertEquals(count, threadOrder.preserveOrderViaJoin() / millisUnit);
        }
    
        @Test
        public void testPreserveOrderViaCountdownLatch() throws InterruptedException {
            ThreadOrder threadOrder = new ThreadOrder();
            Assert.assertEquals(1, threadOrder.preserveOrderViaCountdownLatch() / millisUnit);
        }
    }
  • 相关阅读:
    Android标题栏最右边添加按钮
    Activity标题栏添加返回按钮
    【Android】解决Android横竖屏切换数据丢失问题的方法
    Android热更新,到底是更新啥?
    vm ware 虚拟WIN10 时,chrome ,cent browser 显示异常,花屏
    动态生成的 select option 无法选中,设置值
    安装sql 2012 时遇到“需要更新的以前的 Visual Studio 2010 实例。”规则失败。
    C#.NET 简单使用log4net
    10位,13位时间戳转为C#格式时间
    C# .NET Unix 时间戳
  • 原文地址:https://www.cnblogs.com/hiver/p/7122795.html
Copyright © 2011-2022 走看看