多线程间经常需要协调一批任务线程同时完成之后去做某事,而Java中提供的流程控制有两种方式:一种是CyclicBarrier,另一种是CountDownLatch.
第一种方式 CyclicBarrier。来自jdk的解释:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
第二种方式 CountDownLatch。来自jdk的解释:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。
CountDownLatch 的一个有用特性是,它不要求调用 countDown 方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await。
源码示例如下:
package multiThreadShow;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
public class MultiThreadShow {
public static void main(String[] args){
HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer,ArrayList<Integer>>();
HashMap<Integer, ArrayList<Integer>> map2 = new HashMap<Integer,ArrayList<Integer>>();
for(int i=0;i<50;i++){
ArrayList<Integer> arrayList= new ArrayList<Integer>();
for(int i1=0;i1<10000;i1++){
int p = (int) (Math.random()*10000);
arrayList.add(p);
}
map.put(i, arrayList);
}
for(int i=0;i<50;i++){
ArrayList<Integer> arrayList= new ArrayList<Integer>();
for(int i1=0;i1<10000;i1++){
int p = (int) (Math.random()*10000);
arrayList.add(p);
}
map2.put(i, arrayList);
}
CountDownLatch doneSignal = new CountDownLatch(map.size());
long start = System.currentTimeMillis();
for(int i : map.keySet()){
SortThread t= new SortThread(doneSignal,"SortThread-"+i);
t.setArrayList(map.get(i));
t.start();
}
try {
doneSignal.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Excuting this totally costs "+(end - start));
start = System.currentTimeMillis();
final long input = start;
//其中的Runnable任务用来统计这批任务的执行时间 当所有的任务都达到cyclicBarrier点时(即表示这些任务都完成)
//那么通过这个Runnable任务去统计执行时间
CyclicBarrier cyclicBarrier = new CyclicBarrier(map2.size(),new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Excuting this totally costs "+(System.currentTimeMillis() - input));
}
});
for(int i : map2.keySet()){
SortThreadCyclicBarrier t= new SortThreadCyclicBarrier(cyclicBarrier,"SortThreadCyclicBarrier-"+i);
t.setArrayList(map2.get(i));
t.start();
}
// end = System.currentTimeMillis();
//main 这个线程执行的顺序可能在阻塞期间 所以这个时间点没有用
//System.out.println("Excuting this totally costs "+(end - start));
}
}
//CountDownLatch排序Thread
class SortThread extends Thread{
private ArrayList<Integer> arrayList;
private final CountDownLatch doneSignal;
public ArrayList<Integer> getArrayList() {
return arrayList;
}
public void setArrayList(ArrayList<Integer> arrayList) {
this.arrayList = arrayList;
}
public SortThread(CountDownLatch doneSignal,String name){
super(name);
this.doneSignal = doneSignal;
}
public void run(){
Collections.sort(arrayList);
doneSignal.countDown();
//System.out.println("Sort finished"+this.getName());
}
}
//CyclicBarrier排序Thread
class SortThreadCyclicBarrier extends Thread{
private ArrayList<Integer> arrayList;
private final CyclicBarrier cyclicBarrier;
public ArrayList<Integer> getArrayList() {
return arrayList;
}
public void setArrayList(ArrayList<Integer> arrayList) {
this.arrayList = arrayList;
}
public SortThreadCyclicBarrier(CyclicBarrier cyclicBarrier,String name){
super(name);
this.cyclicBarrier = cyclicBarrier;
}
public void run(){
System.out.println("Sort Start "+this.getName());
Collections.sort(arrayList);
System.out.println("Sort finished "+this.getName());
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
return;
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
return;
}
//System.out.println("Sort finished "+this.getName());
}
}
说明:这两种流程控制手段的区别在于 后者可以循环使用,而且后者控制的线程一个出现问题,则剩下的线程都会以抛出BrokenBarrierException 的方式终止。
分享到:
相关推荐
这里,我们主要探讨的是如何通过编写多线程并发程序来优化应用程序的性能,提高系统的处理能力。 首先,多线程是指在一个进程中同时执行多个线程。线程是操作系统调度的基本单位,它允许程序同时执行多个任务。多...
在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...
本文将深入探讨基于C#的并发流程控制框架,特别是针对高并发场景下的多线程管理和线程安全问题。我们将通过分析`ConsoleTest`这个示例项目,来揭示CsGo并发流程控制框架的核心理念与实践。 一、并发控制基础 并发...
多线程并发是指在一个程序中同时执行多个独立的线程。在API测试中,多线程并发测试意味着模拟多个用户或系统同时调用API,以测试其在并发访问时的行为。这有助于检测并发控制机制(如锁、信号量)是否有效,以及...
在编程领域,多线程并发处理是一种常见的优化技术,它能充分利用多核处理器的资源,提高程序的执行效率。在给定的标题“多线程并发处理的简单实现”中,我们可以深入探讨如何构建这样的系统。 首先,多线程并发处理...
一种典型的多线程并发服务器架构如下: - **主监听线程**:负责接收客户端连接请求。 - **工作线程池**:由多个工作线程组成,负责处理具体的客户端请求。 **3. 示例代码片段** 下面是一个简单的多线程服务器示例...
Java 模拟线程并发是编程领域中的一个重要概念,尤其在多核处理器和高并发应用中,理解并熟练掌握线程并发技术对于提升程序性能至关重要。在Java中,线程并发可以通过多种方式实现,包括继承Thread类、实现Runnable...
在处理大量图像或需要快速响应时间的应用场景中,多线程并发识别可以显著提升效率。以下将详细介绍如何利用Tesseract OCR实现多线程并发识别,以及可能涉及的相关技术点。 首先,理解Tesseract OCR的基本工作原理是...
本文档主要介绍如何使用C#的HttpWebRequest类实现多线程并发HTTP请求,以创建高效的采集蜘蛛程序。 首先,网络爬虫的工作流程通常包括以下几个步骤: 1. **初始化待下载和已下载集合**:为了跟踪URL状态,避免重复...
Java多线程与并发编程是Java语言中用于处理多任务执行的关键技术,它能够帮助开发者设计出能够有效应对高并发请求的应用程序。在现代的线上(Online)和离线(Offline)应用中,合理利用多线程技术可以大幅提高系统...
本项目聚焦于使用Java的Socket进行多线程并发控制,并结合Hibernate ORM框架与MySQL数据库进行数据存储。下面将详细阐述这些技术及其应用。 首先,Java Socket是Java提供的用于实现网络上不同计算机间进程通信的...
在Java中,线程是轻量级的,因为它共享进程的内存空间,这使得多线程成为处理大量并发任务的有效方式。创建Java线程有两种主要方法:通过实现`Runnable`接口或继承`Thread`类。`Runnable`通常更灵活,因为它允许线程...
Java多线程与并发编程是Java...总之,Java多线程与并发编程是Java程序员必须掌握的核心技能,它涉及到操作系统原理、JVM内部机制以及Java提供的各种并发工具,熟练掌握这些知识对于编写高效、稳定的并发程序至关重要。
Java提供了一个强大的多线程支持,允许开发者创建、管理和控制多个执行路径,以提高程序的运行效率。在Java中,可以通过两种方式创建线程:继承Thread类或实现Runnable接口。继承Thread类直接创建一个新的Thread子类...
在Linux操作系统中,多线程并发控制是一个至关重要的主题,特别是在设备驱动编程和系统级开发中。本文将深入探讨Linux下并发控制的原因、方法以及具体的实现机制。 并发控制的主要原因是由于多个线程可能同时访问...
在现代软件开发中,特别是在Java这样的主流编程语言中,多线程并发技术是提高程序执行效率、优化资源利用的关键手段之一。本篇文章将深入探讨Java中的多线程并发机制,并通过具体的示例来帮助读者更好地理解和掌握这...
标题"多线程控制程序_并发_buriedutt_多线程_"指出了我们探讨的主题,即如何管理和控制多线程以实现并发执行,从而提高程序的执行效率和系统资源利用率。 首先,我们要理解什么是并发。并发是指系统在同一时间段内...
在IT行业中,多线程并发处理数据是一种常见的优化策略,特别是在大数据处理、网络服务和分布式系统中。通过并发,可以充分利用多核处理器的计算能力,提高程序执行效率,缩短任务的总体完成时间。本篇文章将深入探讨...
实现多线程的并发执行,能演示操作系统的时间转轮调度算法对多线程程序执行的影响效果,能控制一个或多个线程的执行情况。
但同时,多线程并发也会引入一些问题,如数据竞争和同步问题。 为了解决这些问题,Java提供了多种同步机制。`synchronized`关键字用于控制对共享资源的访问,确保同一时间只有一个线程可以执行特定代码块,从而避免...