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;
        }

        /**
         * ContdownLatch可同时阻塞多个线程,但它们可并发执行
         *
         * @return
         * @throws InterruptedException
         */
        public long preserveOrderViaContdownLatch() 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 testPreserveOrderViaContdownLatch() throws InterruptedException {
        ThreadOrder threadOrder = new ThreadOrder();
        Assert.assertEquals(1, threadOrder.preserveOrderViaContdownLatch() / millisUnit);
    }
}
时间: 2024-08-07 21:20:41

Java多线程系列四——控制线程执行顺序的相关文章

java多线程系列(四)

Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解能让知识更加简单易懂. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线程系列(三)之等待通知机制 java多线程系列(四)之ReentrantLock的使用 ReentrantLock(重入锁) public class

Java多线程——&lt;三&gt;简单的线程执行:Executor

一.概述 按照<Java多线程——<一><二>>中所讲,我们要使用线程,目前都是显示的声明Thread,并调用其start()方法.多线程并行,明显我们需要声明多个线程然后都调用他的start方法,这么一看,似乎有些问题:第一.线程一旦多了,声明势必是个问题:第二.多线程启动如果通过手动执行的话,那可能一个线程已经跑完了,另外一个还没起来(我推测可能会出现这个问题).所以,我们在想,如果有个管家,能够帮我们管理这么多线程,只需要把我们定义的任务交给管家,管家就能够帮我们

gcd 控制线程执行顺序(供参考)

dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程一 }); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程二 }); dispatch_group_notify(group, dispatch_get_

Java多线程系列

参考资料: http://www.jianshu.com/p/40d4c7aebd66 0.环境 Java: jdk1.8.0_91 CPU: Intel Core i5-6500 Memory: 8G 1.说明 本系列文章为Java多线程的学习记录 Java多线程系列一--Java实现线程方法 Java多线程系列二--Thread类的方法 Java多线程系列三--实现线程同步的方法 Java多线程系列四--控制线程执行顺序 Java多线程系列五--列表类 Java多线程系列六--Map实现类

java多线程系列8-线程的优先级

在java中设置线程优先级使用setPriority,在jdk中的源代码如下: public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup())

Java多线程系列十——BlockingQueue类

参考资料:http://ifeve.com/java-synchronousqueue/http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.htmlhttp://ifeve.com/java-blocking-queue/ BlockingQueue的几个API认识 方法 说明 add(E e) 添加元素,超出队列size上限后抛异常 offer(E e) 添加元素,超出队列size上限后抛异常,相比add官方更建议使用offer方

Java多线程(四)、线程池(转)

Java多线程(四).线程池 分类: javaSE综合知识点 2012-09-19 17:46 3943人阅读 评论(1) 收藏 举报 系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似的是,线程池在系统启动时即创建大量空闲的线程,程序将一个Runnable对象传给线程池,线程池就会启动一条线程来执行该对象的run方法,当run方法执行结束后,该线

“全栈2019”Java多线程第四章:设置和获取线程名称

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第四章:设置和获取线程名称 下一章 "全栈2019"Java多线程第五章:线程睡眠sleep()方法详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Jav

“全栈2019”Java多线程第四十二章:获取线程与读写锁的保持数

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第四十二章:获取线程与读写锁的保持数 下一章 "全栈2019"Java多线程第四十三章:查询是否有线程在等待读写锁 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复&quo