美文网首页
谈谈Java中线程的执行顺序

谈谈Java中线程的执行顺序

作者: 雨果是程序员 | 来源:发表于2019-08-01 01:01 被阅读0次

线程执行顺序

我们先来看一个简单的例子,我们显示地创建三个线程t1、t2、t3,按照声明的顺序,依次分别调用线程的start方法,线程的执行顺序是怎样的?程序执行的结果会如何?:

public class ThreadOrderDemo {
    // 显示地创建三个线程,观察执行顺序
    static Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread1");
        }
    });
    static Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread2");
        }
    });
    static Thread t3 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread3");
        }
    });
    public static void main(String[] args) throws Exception {
        t1.start();
        t2.start();
        t3.start();
    }
}

猜测程序执行结果:
1.按照代码顺序执行,依次为t1、t2、t3:

This is thread1
This is thread2
This is thread3

2.按照CPU调度规则,顺序随机:

This is thread1
This is thread3
This is thread2

我们经过编辑器执行,会发现结果是2,按照CPU调度,执行顺序随机。
那我们如何让线程有序执行呢?以下有两种方式。

方式一:使用join让主线程等待

public static void main(String[] args) throws Exception {
        // 方式一:使用join让主线程等待
        t1.start();
        t1.join();

        t2.start();
        t2.join();
        
        t3.start();
    }

上述改写主线程main方法,使用Thread类提供的join方法,可以达到让线程有序执行的效果。

public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

查看Thread类源码,可知,此处join方法,实质上是通过调用Object的wait方法,让主线程等待子线程执行,子线程执行完之后,主线程再执行。

方式二:使用线程池队列

public class ThreadOrderDemo {
    // 显示地创建三个线程,观察执行顺序
    static Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread1");
        }
    });
    static Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread2");
        }
    });
    static Thread t3 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread3");
        }
    });
    static ExecutorService executor = Executors.newSingleThreadExecutor();
  
    public static void main(String[] args) throws Exception {
        // 方式二:使用线程池队列
       executor.submit(t1);
       executor.submit(t2);
       executor.submit(t3);
    }
}

上述使用J.U.C(java.util.concurrent)包中的ExecutorService建立线程池队列,以保持线程有序执行。

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

序号 参数名 类型 含义
1 corePoolSize int 核心线程池大小
2 maximumPoolSize int 最大线程池大小
3 keepAliveTime long 线程最大空闲时间
4 unit TimeUnit 时间单位
5 workQueue BlockingQueue<Runnable> 线程等待队列
6 threadFactory ThreadFactory 线程创建工厂
7 handler RejectedExecutionHandler 拒绝策略

上述Executors.newSingleThreadExecutor()实质是LinkedBlockingQueue,创建了一个阻塞的安全线程队列,FIFO先进先出,所以可以达到线程有序执行的目的。

推荐阅读

谈谈Java中hashCode和equals方法
谈谈Java中==和equals到底有啥区别
从月薪5千到月薪3万,优秀的程序员

相关文章

  • 面试官:Java中线程是按什么顺序执行的?

    摘要:Java中多线程并发的执行顺序历来是面试中的重点,掌握Java中线程的执行顺序不仅能够在面试中让你脱颖而出,...

  • 谈谈Java中线程的执行顺序

    线程执行顺序 我们先来看一个简单的例子,我们显示地创建三个线程t1、t2、t3,按照声明的顺序,依次分别调用线程的...

  • 控制线程的执行顺序

    在Java多线程中通常来说,在执行线程时,如果要保证线程的执行顺序,可以使用join和Executorservic...

  • JAVA 线程

    【JAVA 线程】 线程 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者...

  • 1.2.1线程的启动顺序与start()的执行顺序无关

    执行start()方法的顺序不代表线程启动的顺序。 执行结果 摘选自 java多线程核心编程技术-1.2.1

  • Java 线程 - 线程顺序执行

    1 三个线程顺序打出abc 2 三个线程顺序打出abc 30次[Semaphore] 3 三个线程顺序打出abc ...

  • 多线程与多进程

    python中一个进程中的多线程是要排队的,就好像一个线程按顺序执行,但是java中多线程是可以并发执行的。 对于...

  • 笔记 34 | java线程之Thread线程优先

    地址 笔记 34 | java线程之Thread线程优先 前言 当我们需要在几个线程中拍个优先执行的顺序时,我们就...

  • Java程序的顺序问题

    一、Java中的执行顺序 二、Java中的赋值顺序 一、Java中的执行顺序 1.静态块2.块3.构造器4.父类构...

  • jmeter组件分类及执行顺序

    point jmeter中组件执行顺序: 1、配置元件:相当于Java中的常量和变量定义,可以跨线程组使用。HTT...

网友评论

      本文标题:谈谈Java中线程的执行顺序

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