如何控制线程的执行顺序

错误示例:

 1 public class Test {
 2     public static void main(String[] args){
 3         thread1.start();
 4         thread2.start();
 5         thread3.start();
 6     }
 7
 8     static Thread thread1 = new Thread(new Runnable() {
 9         @Override
10         public void run() {
11             System.out.println("thread1");
12         }
13     });
14
15     static Thread thread2 = new Thread(new Runnable() {
16         @Override
17         public void run() {
18             System.out.println("thread2");
19         }
20     });
21
22     static Thread thread3 = new Thread(new Runnable() {
23         @Override
24         public void run() {
25             System.out.println("thread3");
26         }
27     });
28 }

执行结果:

1 thread2
2 thread1
3 thread3

原因:start()方法只是让子线程处于就绪状态,最终执行状态是不可控的

方案一:

 1 public class Test {
 2     public static void main(String[] args) throws InterruptedException {
 3         thread1.start();
 4         thread1.join();//主线程放弃cpu执行权,让给子线程执行
 5         thread2.start();
 6         thread2.join();
 7         thread3.start();
 8         thread3.join();
 9     }
10
11     static Thread thread1 = new Thread(new Runnable() {
12         @Override
13         public void run() {
14             System.out.println("thread1");
15         }
16     });
17
18     static Thread thread2 = new Thread(new Runnable() {
19         @Override
20         public void run() {
21             System.out.println("thread2");
22         }
23     });
24
25     static Thread thread3 = new Thread(new Runnable() {
26         @Override
27         public void run() {
28             System.out.println("thread3");
29         }
30     });
31 }

结果:

1 thread1
2 thread2
3 thread3

join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。

源码:

 1 public final synchronized void join(long millis)
 2     throws InterruptedException {
 3         long base = System.currentTimeMillis();
 4         long now = 0;
 5
 6         if (millis < 0) {
 7             throw new IllegalArgumentException("timeout value is negative");
 8         }
 9
10         if (millis == 0) {
11             while (isAlive()) {
12                 wait(0);
13             }
14         } else {
15             while (isAlive()) {
16                 long delay = millis - now;
17                 if (delay <= 0) {
18                     break;
19                 }
20                 wait(delay);
21                 now = System.currentTimeMillis() - base;
22             }
23         }
24     }
wait(0)是当前主线程进入等待
方案二:
 1 public class Test {
 2     public static void main(String[] args) throws InterruptedException {
 3         executorService.submit(thread1);
 4         executorService.submit(thread2);
 5         executorService.submit(thread3);
 6     }
 7
 8     static ExecutorService executorService = Executors.newSingleThreadExecutor();
 9
10     static Thread thread1 = new Thread(new Runnable() {
11         @Override
12         public void run() {
13             System.out.println("thread1");
14         }
15     });
16
17     static Thread thread2 = new Thread(new Runnable() {
18         @Override
19         public void run() {
20             System.out.println("thread2");
21         }
22     });
23
24     static Thread thread3 = new Thread(new Runnable() {
25         @Override
26         public void run() {
27             System.out.println("thread3");
28         }
29     });
30 }

执行结果:

thread1
thread2
thread3

单线程化线程池(newSingleThreadExecutor)的优点,串行执行所有任务

 

原文地址:https://www.cnblogs.com/chinano1/p/9981368.html

时间: 2024-10-08 08:37:31

如何控制线程的执行顺序的相关文章

关于CountDownLatch控制线程的执行顺序

在上一篇文章中说过使用thread.join()方法.newSingleThreadExecutor单线程池来控制线程执行顺序.在文章的末尾我提出了一种构想,可否使用经典的生产者和消费者模型来控制执行顺序.在本文中,我将使用CountDownLatch来解决这个问题. 上图是countDownLatch的原理示意图.官方文档给出的解释是:CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行.上图中线程A调用方法await()之后,进行阻塞,然后线

线程的执行顺序

线程的执行完全是自发的去抢CPU时间片,谁先抢到谁就先去执行package com.pers.xiancheng; public class Test implements Runnable { int count;//默认是0 static Object obj = new Object(); @Override public void run() { //synchronized块锁定的是整个对象 synchronized (obj) {//synchronized 是用来获得对象锁,只有获

采用闭锁(CountDownLatch)控制线程的先后顺序(一)

CountDownLatch俗称闭锁,可以初始化一个值,每执行一次countDown()操作,值减一,减为0时,在闭锁前等待的线程即可执行,但是闭锁的值不能恢复,即一次性.下面是api文档中的介绍: A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown()

如何保证线程的执行顺序

示例代码 static Thread t1 = new Thread(new Runnable() { public void run() { System.out.println("Thread1"); } }); static Thread t2 = new Thread(new Runnable() { public void run() { System.out.println("Thread2"); } }); static Thread t3 = new

采用闭锁(CountDownLatch)控制线程的先后顺序(二)

还是上一篇的应用场景,将小明与小强持有的闭锁,合二为一,优化后的代码如下: package com.smikevon.concurrent.tools; import java.util.concurrent.CountDownLatch; /** * @description: 要求:妈妈炒菜,但是这个时候还没买菜,也没有酱油了.为了更快的吃上饭,妈妈,小明,小强,分别行动, * 妈妈负责敲响做饭铃(铃响之前不许动),兄弟二人就可以出发,然后妈妈收拾厨房调好料,小明负责买菜,小强负责买酱油,协

如何控制多线程的执行顺序

问题描述: Thread thread1 = new Thread(new Runnable() { public void run() { for (int i = 0; i < 1000; i++) { System.out.println(Thread.currentThread().getName() + "...." + i); } } }); Thread thread2 = new Thread(new Runnable() { public void run()

Servlet 3.0 之@WebFilter怎么控制多个filter的执行顺序

之前我们控制多个filter的执行顺序是通过web.xml中控制filter的位置来控制的,放在上面的会比放在下面的先执行,如下“用户登录检查过滤器”会比“接口日志过滤器”先执行   <!-- 用户登录检测过滤器 -->    <filter> <filter-name>UserLoginFilter</filter-name>         <filter-class>net.tfgzs.demo.filter.UserLoginFilter

多线程总结三:控制线程

Java的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好的控制线程的执行. 1.join线程:join 当某个程序执行流中调用其他线程的join()方法时,执行中的线程会被阻塞,直到被join()方法加入的join线程执行完为止.join()方法将大问题划分为许多小问题,每个小问题分配一个线程,当所有的小问题都得到处理以后,再调用主线程来进一步操作. 1 /** 2 * @Title: JoinThread.java 3 * @Package 4 * @author 任伟 5

Java 控制线程

Java 的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程的执行. join 线程 Thread 提供了让一个线程等待另一个线程完成的方法—— join() 方法.当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被 join() 方法加入的 join 线程执行完为止. join() 方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程.当所有的小问题都得到处理后,再调用主线程来进一步操作. public clas