`

多个线程到达后才能执行某个任务,并且只能执行一次

阅读更多
有一种场景:多个线程到达(比如合并多个线程返回的结果)后才能执行某个任务,并且只能执行一次。

有几种方式:
1、Thread的join,不再讲解,因为使用不方便,也是不建议使用的方式。
2、AtomicInteger ,其increaseAndGet 是非常方便实现这个需求的。
3、CountDownLatch ,这个组件也可以,并且在特定场景下,这个是最好的实现,比如有时间等待限制的。

下面看这个2 和 3的case。

import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 
 * @author xinchun.wang
 * @email: 532002108@qq.com
 * @createTime 2015-4-2 下午11:25:26
 */
public class AtomicExecute {
	private static final int all = 3;

	public static void main(String[] args) throws Exception {
		Vector<Integer> vector = new Vector<Integer>();
		AtomicInteger mask = new AtomicInteger(0);
		TestThread t1 = new TestThread(mask, vector, 1, 10);
		TestThread t2 = new TestThread(mask, vector, 11, 20);
		TestThread t3 = new TestThread(mask, vector, 21, 30);
		t1.start();
		t2.start();
		t3.start();

		Vector<Integer> vectorMain = new Vector<Integer>();
		for (int i = 1; i <= 30; i++) {
			vectorMain.add(i * i * i);
		}
		System.out.println("vectorMain: " + addVector(vectorMain));

	}

	private static long addVector(Vector<Integer> vector) {
		long result = 0;
		for (Integer item : vector) {
			result = result + item;
		}
		return result;
	}

	public static class TestThread extends Thread {
		private final AtomicInteger mask;
		private final Vector<Integer> vector;
		private int begin;
		private int end;

		public TestThread(AtomicInteger mask, Vector<Integer> vector,
				int begin, int end) {
			this.mask = mask;
			this.vector = vector;
			this.begin = begin;
			this.end = end;
		}

		@Override
		public void run() {
			for (int i = begin; i <= end; i++) {
				vector.add(i * i * i);
			}
			// do some things
			if (mask.incrementAndGet() == all) {
				System.out.println("vector: " + addVector(vector));
			}
		}
	}

}


/**
 * 
 * @author xinchun.wang
 * @email: 532002108@qq.com
 * @createTime 2015-4-2 下午11:25:26
 */
public class CountDown {
	private static final int all = 3;

	public static void main(String[] args) throws Exception {
		Vector<Integer> vector = new Vector<Integer>();
		CountDownLatch mask = new CountDownLatch(all);
		TestThread t1 = new TestThread(mask, 1, 10, vector);
		TestThread t2 = new TestThread(mask, 11, 20, vector);
		TestThread t3 = new TestThread(mask, 21, 30, vector);
		TestThread2 t4 = new TestThread2(mask, vector);
		t4.start();
		t1.start();
		t2.start();
		t3.start();

		Vector<Integer> vectorMain = new Vector<Integer>();
		for (int i = 1; i <= 30; i++) {
			vectorMain.add(i * i * i);
		}
		System.out.println("vectorMain: " + addVector(vectorMain));
	}

	private static long addVector(Vector<Integer> vector) {
		long result = 0;
		for (Integer item : vector) {
			result = result + item;
		}
		return result;
	}

	/**
	 * 输出结果的线程
	 */
	public static class TestThread2 extends Thread {
		private final CountDownLatch mask;
		private final Vector<Integer> vector;

		public TestThread2(CountDownLatch mask, Vector<Integer> vector) {
			this.mask = mask;
			this.vector = vector;
		}

		@Override
		public void run() {
			try {
				mask.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("vector: " + addVector(vector));
		}
	}

	/**
	 * 实际添加数据的线程
	 */
	public static class TestThread extends Thread {
		private final CountDownLatch mask;
		private int begin;
		private int end;
		private Vector<Integer> vector;

		public TestThread(CountDownLatch mask, int begin, int end,
				Vector<Integer> vector) {
			this.mask = mask;
			this.begin = begin;
			this.end = end;
			this.vector = vector;
		}

		@Override
		public void run() {
			for (int i = begin; i <= end; i++) {
				vector.add(i * i * i);
			}
			mask.countDown();
		}
	}
}
0
0
分享到:
评论

相关推荐

    向量在同一个块中用多个线程执行

    总结来说,"向量在同一个块中用多个线程执行"是指利用CUDA的线程块模型,将计算任务分散到多个线程中,以提高GPU的并行计算能力。在这个实验中,我们看到一个包含10个线程的线程块,可能用于执行某种循环计算,如...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例).rar

    - 死锁是多线程编程中常见的问题,多个线程互相等待对方释放资源导致无法继续执行。理解和避免死锁是多线程编程的必备技能。 以上知识点是C#.NET多线程实例中可能会涉及到的核心内容,通过学习这些实例,开发者...

    多线程的批量线程同步解决方案

    多线程是指在一个进程中同时执行多个线程。这使得应用程序能够并行处理任务,提高系统资源利用率,尤其是在多核处理器中,可以显著提升性能。Java、Python、C++等编程语言都提供了丰富的多线程支持。 二、线程同步 ...

    linux多定时器多线程

    1. **线程定义**:线程是程序执行的最小单位,一个进程可以包含多个线程,它们共享同一地址空间,资源利用率高,通信成本低。 2. **创建线程**:在Linux中,可以使用pthread库中的`pthread_create()`函数创建新线程...

    Java多线程编程经验

    障碍器(`CyclicBarrier`)是一种协调多个线程的工具,使得所有参与的线程都必须等待到达某个屏障点后才能继续执行。 #### 二十二、Java线程:大总结 Java多线程编程是Java开发中的重要部分,涉及到线程的创建、...

    40个Java多线程问题总结

    - `CyclicBarrier`是一个同步辅助类,用于协调多个线程的工作。当所有参与线程都到达指定屏障点时,它们将被释放并继续执行。这个屏障点可以被多次重置和使用,因此称为“循环”。 - 如果某个线程提前到达屏障点,...

    多线程面试题

    在计算机科学中,多线程是一种允许一个进程同时执行多个线程的技术,目的是为了提高程序的执行效率。多线程面试题往往会围绕线程的概念、特性、线程安全、锁机制以及多线程编程中可能遇到的问题和解决方案进行提问。...

    史上最全 Java 多线程面试题及答案

    - **CountDownLatch**:每个线程到达点后计数器减1,当计数器归零时,所有等待的线程可以继续执行,不可重用,适用于一次性同步控制。 了解这些核心概念后,开发者可以更好地应对Java多线程面试中可能出现的问题,...

    多线程demo/java多线程练习

    在Java编程中,多线程是一项关键技能,它能让程序同时执行多个任务,提升系统效率。本项目"多线程demo/java多线程练习"旨在通过实际操作来深入理解和掌握多线程技术,同时模拟数据库操作,这在现代应用程序开发中至...

    C# 线程间操作

    - `Barrier`类:用于多个线程到达特定点后同步执行下一步操作。 - `CountdownEvent`:当计数器归零时,所有等待的线程被释放,常用于并发测试。 3. **线程状态管理**:C#提供了一些API来管理线程状态,如`Thread....

    Java多线程端口快速扫描

    - `CyclicBarrier`:循环栅栏,允许一组线程等待其他线程到达某个点,然后一起继续执行。 4. **TCP连接与套接字编程** - `Socket`类:代表TCP连接,用于发送和接收数据。 - `ServerSocket`类:用于监听和接受...

    多线程控制

    多线程是计算机编程中的一个核心概念,它允许在一个程序中同时执行多个任务或子任务,从而提高程序的效率和响应性。在按键精灵(AutoIt)这样的自动化脚本工具中,多线程的应用尤为广泛,可以实现更加复杂和灵活的...

    多线程测试程序

    例如,它可能创建多个线程,每个线程都调用`WaitForSingleObject`或`WaitForMultipleObjects`来等待特定的事件,然后观察和分析线程间的同步行为是否符合预期。这样的测试对于确保多线程应用程序的正确性和可靠性至...

    Linux多线程编程_linux_

    条件变量允许线程等待特定条件满足后再继续执行,而屏障则确保一组线程在到达某个点之前都必须停止,直到所有线程都到达后才能继续。 线程的生命周期管理也是重要的一环。`pthread_join()`函数用于等待线程结束并...

    Java多线程资料

    - CyclicBarrier:循环屏障,允许多个线程同步到达某个点后再继续执行。 - Semaphore:信号量,控制同时访问特定资源的线程数量。 - Phaser:更强大的同步工具,支持分阶段的同步。 7. **死锁、活锁与饥饿** - ...

    C#多线程编程实战 源代码

    - `Barrier`:允许多个线程同步到达某个点,然后继续执行。 - `Channel`:.NET Core中的高级同步原语,用于线程间的数据传递。 4. **异步编程与任务并行库(TPL)**: - `Task`类:代表异步操作,可以更高效地利用...

    Java多线程编程总结

    - 线程总是隶属于某个进程,同一进程内的多个线程共享内存空间。 2. **Java中的线程** - 在Java中,“线程”有两层含义: - `java.lang.Thread` 类的一个实例。 - 线程的执行过程。 - 使用 `java.lang.Thread`...

    java并发(二十四)多线程结果组装

    这通常需要一种机制来收集每个线程完成后的结果,并确保在所有线程都完成工作后进行整合。 在Java中,可以使用`Future`和`ExecutorService`接口来实现这一目标。`ExecutorService`允许我们创建并管理一组线程,而`...

    Java多线程运算集合

    - **线程**:是进程中的一个执行单元,一个进程中可以包含多个线程,这些线程共享同一个进程的内存资源。 - **多任务与多线程**: - 多任务是指操作系统能够同时处理多个任务的能力,而多线程则是实现多任务的一...

Global site tag (gtag.js) - Google Analytics