有三个线程,怎么让他们按顺序执行?

场景:有三个线程t1、t2、t3。确保三个线程t1执行完后t2执行,t2执行完成后t3执行。

方法1:thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

package com.gs.demo1;

public class ThreadTest1 {

	public static void main(String[] args) {
		Thread t1 = new Thread(new Work(null),"线程t1");
		Thread t2 = new Thread(new Work(t1),"线程t2");
		Thread t3 = new Thread(new Work(t2),"线程t3");

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

	static class Work implements Runnable{
		private Thread beforeThread;
		public Work(Thread beforeThread) {
			this.beforeThread = beforeThread;
		}
		@Override
		public void run() {
			if(beforeThread!=null) {
				try {
					//某线程调用该方法,会让其他线程处于等待状态,让其运行完毕,再执行其他线程.
					beforeThread.join();
					System.out.println("Thread start:"+Thread.currentThread().getName());
				}catch(Exception e){
					e.printStackTrace();
				}
			}else {
				System.out.println("Thread start:"+Thread.currentThread().getName());
			}

		}
	}
}

  

  

方法2:使用CountDownLatch

CountDownLatch(闭锁)是一个很有用的工具类,利用它我们可以拦截一个或多个线程使其在某个条件成熟后再执行。它的内部提供了一个计数器,在构造闭锁时必须指定计数器的初始值,且计数器的初始值必须大于0。另外它还提供了一个countDown方法来操作计数器的值,每调用一次countDown方法计数器都会减1,直到计数器的值减为0时就代表条件已成熟,所有因调用await方法而阻塞的线程都会被唤醒。这就是CountDownLatch的内部机制,看起来很简单,无非就是阻塞一部分线程让其在达到某个条件之后再执行。

package com.gs.demo2;

import java.util.concurrent.CountDownLatch;

public class ThreadTest2 {
	public static void main(String[] args) {
		CountDownLatch c1 = new CountDownLatch(0);//计数器为0
		CountDownLatch c2 = new CountDownLatch(1);//计数器为1
		CountDownLatch c3 = new CountDownLatch(1);//计数器为1

		Thread t1 = new Thread(new Work(c1, c2),"线程t1");
	    //c1为0,t1线程可以执行。t1线程的计数器 c2 减1

	    Thread t2 = new Thread(new Work(c2, c3),"线程t2");
	    //t1的计数器c2为0时,t2才能执行。t2的计数器c3减1

	    Thread t3 = new Thread(new Work(c3, c3),"线程t3");
	    //t3的计数器c3为0时,t3才能执行

	    t1.start();
	    t2.start();
	    t3.start();
	}
	//定义Work线程类,需要传入开始和结束的CountDownLatch参数
	static class Work implements Runnable {
		private CountDownLatch c1;
		private CountDownLatch c2;
		public Work(CountDownLatch c1, CountDownLatch c2) {
			super();
			this.c1 = c1;
			this.c2 = c2;
		}

		@Override
		public void run() {
			 try {
				//当某个线程调用CountDownLatch对象的await方法时,将会阻塞,直到计数器的值变成0才放行。
				c1.await();
				System.out.println("thread start:" + Thread.currentThread().getName());
		        c2.countDown(); //本线程计数器减 1
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
	}
}

  

参考文献:https://www.cnblogs.com/kaleidoscope/p/9877174.html

原文地址:https://www.cnblogs.com/gshao/p/10527403.html

时间: 2024-11-07 16:15:54

有三个线程,怎么让他们按顺序执行?的相关文章

C#编程总结(三)线程同步

C#编程总结(三)线程同步 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力.否则,在完全满足前一个请求之前,将无法处理每个新请求.然而,线程的异步特性意味着必须协调对资源(如文件句柄.网络连接和内存)的访问.否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作. "如果觉得有用,请帮顶! 如果有

java多线程学习(三)——线程栈

一.线程栈模型 线程栈模型是理解线程调度原理以及线程执行过程的基础.线程栈是指某时刻时内存中线程调度的栈信息,当前调用的方法总是位于栈顶,线程栈的内容是随着线程的运行状态变化而变化的,研究线程栈必须选择一个运行的时刻(指代码运行到什么地方) 上图中的栈A是主线程main的运行栈信息,当执行new JavaThreadDemo().threadMethod();方法时,threadMethod方法位于主线程栈中的栈顶,在threadMethod方法中运行的start()方法新建立了一个线程,此时,

Java多线程:用三个线程控制循环输出10次ABC

题目:有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C,要求, 同时启动三个线程, 按顺序输出ABC, 循环10次. 解题思路:要按顺序输出ABC, 循环10次,就要控制三个线程同步工作,也就是说要让三个线程轮流输出,直到10个ABC全部输出则结束线程.这里用一个Lock对象来控制三个线程的同步.用一个int型变量state标识由那个线程输出. 1 package com.thread; 2 3 import java.util.concurrent.locks.Lock;

现有T1、T2、T3三个线程,你怎样保证T2在T1执行完成之后执行,T3在T2执行完后执行?

考察join /**  * 现有T1.T2.T3三个线程,你怎样保证T2在T1执行完成之后执行,T3在T2执行完后执行?  * @author user  *  */ public class Test3 { public static void main(String[] args) throws InterruptedException { Thread T1 = new Thread(new T1()); Thread T2 = new Thread(new T2()); Thread T

Java 多线程(三) 线程的生命周期及优先级

Java 多线程(三) 线程的生命周期及优先级 线程的生命周期 线程的生命周期:一个线程从创建到消亡的过程. 如下图,表示线程生命周期中的各个状态: 线程的生命周期可以分为四个状态: 1.创建状态: 当用new操作符创建一个新的线程对象时,该线程处于创建状态. 处于创建状态的线程只是一个空的线程对象,系统不为它分配资源. 2.可运行状态: 执行线程的start()方法将为线程分配必须的系统资源,安排其运行,并调用线程体——run()方法,这样就使得该线程处于可运行状态(Runnable). 这一

java多线程三之线程协作与通信实例

多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition.     附加 : 用监视器进行线程间通信 2.生产者消费者实现,使用LinkedList自写缓冲区. 3.多线程之阻塞队列学习,用阻塞队列快速实现生产者消费者模型.    附加:用布尔变量关闭线程        在三种线程同步方法中,我们这里的实例用Lock锁来实现变量同步,因为它比较灵活直观.

启动三个线程A,B,C,按ABC的顺序输出10次

package jun; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /**  * 启动三个线程A,B,C,

第三章线程同步辅助类

Java 7 并发编程实战手册目录 代码下载(https://github.com/Wang-Jun-Chao/java-concurrency) 第三章线程同步辅助类 3.1简介 ?信号量(Semaphore):是一种计数器,用来保护一个或者多个共享资源的访问.它是并发编程的一种基础工具,大多数编程语言都提供了这个机制. ? CountDownLatch:是Java语言提供的同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待. ? CyclicBarrier也是Java语言

三个线程循环打印ABC10次的几种解决方法

题目:有三个线程分别打印A.B.C,请用多线程编程实现,在屏幕打印10次ABC 整体思路:该问题为三个线程的同步唤醒机制即ThreadA->ThreadB->ThreadC->ThreadA循环执行三个线程. public class MyThreadPrinter2 implements Runnable { private String name; private Object prev; private Object self; private Thread thread; pub

实现多线程的同时复制(三个线程同时复制)

1 package com.threadcopyfile; 2 3 /** 4 * @author lisj 5 * 实现多线程的同时复制 6 * 调用多个线程同时复制各自的模块 7 */ 8 public class threadCopy { 9 10 11 public static void main (String args[]){ 12 13 ThreadCopyFile a=new ThreadCopyFile(1); //实例化多个线程 14 ThreadCopyFile b=ne