Countdownlatch、CyclicBarrier、join区别

本文深入探讨了Java中线程控制的四种主要方法:join、CountDownLatch、CyclicBarrier及分阶段控制策略。通过具体代码示例,对比分析了这些方法在控制线程同步与等待时的不同应用场景与特性。

1、join
模拟现在有三个worker,采用join的方法控制:

package org.pbccrc.org.pbccrc.thread;

public class Test {

	 public static void main(String[] args) throws InterruptedException {
		Worker worker1=new Worker("第一个任务", (int)(Math.random()*1000+2000));
		Worker worker2=new Worker("第二个任务", (int)(Math.random()*1000+2000));
		Worker worker3=new Worker("第三个任务", (int)(Math.random()*1000+2000));
		
		Thread thread1 =new Thread(worker1);
		Thread thread2 =new Thread(worker2);
		Thread thread3 =new Thread(worker3);
		
		thread1.start();
		thread2.start();
		
		thread1.join();
		thread2.join();
		
		System.out.println("wait thread1 and thread2 complete :");
		thread3.start();
		thread3.join();
		
		System.out.println("three threads have complete!");
		
	}
	
}

package org.pbccrc.org.pbccrc.thread;

public class Worker implements Runnable {

	 private String name;
	 
	 private int time;
	 
	public Worker(String name, int time) {
		super();
		this.name = name;
		this.time = time;
	}


	@Override
	public void run() {
       System.out.println("task :"+name+":is running!");
       try {
		Thread.sleep(time);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
       System.out.println("task :"+name+":complete!");
		
	}

}

task :第一个任务:is running!
task :第二个任务:is running!
task :第二个任务:complete!
task :第一个任务:complete!
wait thread1 and thread2 complete :
task :第三个任务:is running!
task :第三个任务:complete!
three threads have complete!

2Countdownlatch
采用countDownlatch控制:

package org.pbccrc.org.pbccrc.thread;

import java.util.concurrent.CountDownLatch;

public class Test {

	 public static void main(String[] args) throws InterruptedException {
		 CountDownLatch latch=new CountDownLatch(2);
		Worker worker1=new Worker("第一个任务", (int)(Math.random()*1000+2000),latch);
		Worker worker2=new Worker("第二个任务", (int)(Math.random()*1000+2000),latch);
		Worker worker3=new Worker("第三个任务", (int)(Math.random()*1000+2000),latch);
		
		
		Thread thread1 =new Thread(worker1);
		Thread thread2 =new Thread(worker2);
		Thread thread3 =new Thread(worker3);
		
		thread1.start();
		thread2.start();
		
		latch.await();
		
		System.out.println("wait thread1 and thread2 complete :");
		thread3.start();
		thread3.join();
		System.out.println("three threads have complete!");
		
	}
	
}

package org.pbccrc.org.pbccrc.thread;

import java.util.concurrent.CountDownLatch;

public class Worker implements Runnable {

	 private String name;
	 
	 private int time;
	 
	 private CountDownLatch latch;
	 
	public Worker(String name, int time,CountDownLatch latch) {
		super();
		this.name = name;
		this.time = time;
		this.latch = latch;
	}


	@Override
	public void run() {
       System.out.println("task :"+name+":is running!");
       try {
		Thread.sleep(time);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
       System.out.println("task :"+name+":complete!");
	   latch.countDown();	
	}

}

task :第二个任务:is running!
task :第一个任务:is running!
task :第二个任务:complete!
task :第一个任务:complete!
wait thread1 and thread2 complete :
task :第三个任务:is running!
task :第三个任务:complete!
three threads have complete!

我们发现好像join与countdownlatch没有区别:看下面的例子吧:

3、分阶段控制使用countdownlatch

package org.pbccrc.org.pbccrc.thread;

import java.util.concurrent.CountDownLatch;

public class Worker implements Runnable {

	 private String name;
	 
	 private int time;
	 
	 private CountDownLatch latch;
	 
	public Worker(String name, int time,CountDownLatch latch) {
		super();
		this.name = name;
		this.time = time;
		this.latch = latch;
	}


	@Override
	public void run() {
       System.out.println("task :"+name+":is running for first process!");
       try {
		Thread.sleep(time);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
       
       latch.countDown();	
       
      
       try {
    	System.out.println("task :"+name+":is begin for second process!");
   		Thread.sleep(time);
   		System.out.println("task :"+name+":is complete for second process!");
   	} catch (InterruptedException e) {
   		e.printStackTrace();
   	}
       System.out.println("task :"+name+":complete!");
	  
	}

}

task :第一个任务:is running for first process!
task :第二个任务:is running for first process!
task :第一个任务:is begin for second process!
task :第二个任务:is begin for second process!
wait thread1 and thread2 complete :
task :第三个任务:is running for first process!
task :第一个任务:is complete for second process!
task :第一个任务:complete!
task :第二个任务:is complete for second process!
task :第二个任务:complete!
task :第三个任务:is begin for second process!
task :第三个任务:is complete for second process!
task :第三个任务:complete!
three threads have complete!

区别在:线程执行过程中我们可以使用countdownlatch的方法countDown;countdownlatch是减数器,当数量为0时会唤醒其他的线程执行;

4、CyclicBarrier

public class Test {

	 public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
		 CyclicBarrier barrier=new CyclicBarrier(3);
		Worker worker1=new Worker("第一个任务", (int)(Math.random()*1000+2000),barrier);
		Worker worker2=new Worker("第二个任务", (int)(Math.random()*1000+2000),barrier);
		Worker worker3=new Worker("第三个任务", (int)(Math.random()*1000+2000),barrier);
		
		
		Thread thread1 =new Thread(worker1);
		Thread thread2 =new Thread(worker2);
		Thread thread3 =new Thread(worker3);
		
		thread1.start();
		thread2.start();
		thread3.start();
		
	}
	
}
public class Worker implements Runnable {

	 private String name;
	 
	 private int time;
	 
	 private CyclicBarrier  barrier;
	 
	public Worker(String name, int time,CyclicBarrier barrier) {
		super();
		this.name = name;
		this.time = time;
		this.barrier = barrier;
	}


	@Override
	public void run() {
       try {
			Thread.sleep(time);
			System.out.println("task :"+name+":has already!");
			barrier.await();
			System.out.println("task :"+name+":run !");
			Thread.sleep(time);
		} catch (Exception e) {
			e.printStackTrace();
		}
       System.out.println("task :"+name+":complete!");
	  
	}

}
task :第二个任务:has already!
task :第一个任务:has already!
task :第三个任务:has already!
task :第二个任务:run !
task :第三个任务:run !
task :第一个任务:run !
task :第二个任务:complete!
task :第一个任务:complete!
task :第三个任务:complete!

5、区别:CyclicBarrier和CountDownLatch
在这里插入图片描述

内容概要:本文详细介绍了一个基于Java和Vue的联邦学习隐私保护推荐系统的设计与实现。系统采用联邦学习架构,使用户数据在本地完成模型训练,仅上传加密后的模型参数或梯度,通过中心服务器进行联邦平均聚合,从而实现数据隐私保护与协同建模的双重目标。项目涵盖完整的系统架构设计,包括本地模型训练、中心参数聚合、安全通信、前后端解耦、推荐算法插件化等模块,并结合差分隐私与同态加密等技术强化安全性。同时,系统通过Vue前端实现用户行为采集与个性化推荐展示,Java后端支撑高并发服务与日志处理,形成“本地训练—参数上传—全局聚合—模型下发—个性化微调”的完整闭环。文中还提供了关键模块的代码示例,如特征提取、模型聚合、加密上传等,增强了项目的可实施性与工程参考价值。 适合人群:具备一定Java和Vue开发基础,熟悉Spring Boot、RESTful API、分布式系统或机器学习相关技术,从事推荐系统、隐私计算或全栈开发方向的研发人员。 使用场景及目标:①学习联邦学习在推荐系统中的工程落地方法;②掌握隐私保护机制(如加密传输、差分隐私)与模型聚合技术的集成;③构建高安全、可扩展的分布式推荐系统原型;④实现前后端协同的个性化推荐闭环系统。 阅读建议:建议结合代码示例深入理解联邦学习流程,重点关注本地训练与全局聚合的协同逻辑,同时可基于项目架构进行算法替换与功能扩展,适用于科研验证与工业级系统原型开发。
源码来自:https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
<think>好的,用户问的是Thread.join、sleep和CountDownLatch区别。我需要先回忆这三个Java并发工具的作用和使用场景。 首先,Thread.join的作用是让当前线程等待另一个线程执行完毕。比如线程A调用了线程B的join方法,A会阻塞直到B完成。这适用于线程顺序执行的场景,比如主线程需要等待子线程完成任务后再继续。 然后是sleep,这个比较简单,是让当前线程暂停执行一段时间,不释放锁。主要用于模拟延迟或定时操作,但需要注意异常处理。 CountDownLatch是一个同步辅助类,允许一个或多个线程等待其他线程完成操作。它通过计数器来实现,当计数器减到零时,等待的线程被释放。适用于多个线程协作完成任务的场景,比如并发测试时等待所有线程准备好再开始。 接下来要比较它们的区别。首先功能上,join是线程级别的等待,sleep是暂停当前线程,CountDownLatch是基于计数的协作。其次使用场景不同,join用于线程顺序,sleep用于定时,CountDownLatch用于多线程同步。另外,是否释放锁方面,sleep不释放,join也不释放,而CountDownLatch的await方法会释放锁(如果是基于AQS实现的话)。 还要注意CountDownLatch是一次性的,计数器不能重置,而CyclicBarrier可以循环使用。不过用户没提到CyclicBarrier,暂时不需要比较。用户可能是在开发多线程应用时遇到了选择哪个工具的问题,需要明确各自适用的情况。 可能用户需要实际的例子来区分。比如用join来确保线程执行顺序,用sleep控制时间间隔,用CountDownLatch做并发测试的起跑线。另外,异常处理方面,join和sleep都需要处理InterruptedException,而CountDownLatch的await方法同样需要处理异常。 还要考虑它们的底层实现。join内部可能基于Object的wait方法,sleep是Thread的方法,而CountDownLatch基于AQS。这可能影响性能和使用方式。 最后,总结它们的核心区别,从功能、使用场景、是否释放锁、可重用性等方面对比。确保用户能清楚在不同情况下如何选择。 </think>### **Thread.join、sleep 与 CountDownLatch区别详解** | **特性** | **`Thread.join()`** | **`Thread.sleep()`** | **`CountDownLatch`** | |------------------------|-----------------------------------------|-----------------------------------------|------------------------------------------| | **功能** | 等待**目标线程执行完成** | **暂停当前线程**指定时间 | 等待**多个线程或操作完成**(计数器归零) | | **适用场景** | 线程顺序执行(如主线程等待子线程完成) | 模拟延迟、定时任务 | 多线程协作(如并发测试、任务分阶段启动) | | **是否释放锁** | 否(持有锁时阻塞) | 否(不涉及锁) | 是(`await()`会释放锁,进入等待队列) | | **阻塞对象** | 当前线程等待**目标线程** | 当前线程等待**自身暂停** | 当前线程等待**计数器归零** | | **可重用性** | 一次性(线程结束后自动释放) | 可重复调用 | 一次性(计数器归零后不可重置) | | **异常处理** | 需捕获`InterruptedException` | 需捕获`InterruptedException` | 需捕获`InterruptedException` | | **底层实现** | 基于`Object.wait()`实现 | JVM本地方法实现 | 基于AQS(AbstractQueuedSynchronizer) | --- ### **具体使用对比** #### **1. `Thread.join()`** ```java public class JoinExample { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(() -> { // 子线程任务 System.out.println("子线程运行中..."); }); t.start(); t.join(); // 主线程等待t执行完毕 System.out.println("主线程继续执行"); } } ``` - **特点**: - 适用于**线程间顺序依赖**(如A线程必须等B线程完成才能执行)。 - `join()`可带超时参数(`join(long millis)`),避免永久阻塞。 --- #### **2. `Thread.sleep()`** ```java public class SleepExample { public static void main(String[] args) { try { System.out.println("主线程暂停2秒"); Thread.sleep(2000); System.out.println("主线程恢复"); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` - **特点**: - 用于**定时控制**或模拟延迟(如网络请求重试)。 - 不涉及线程协作,仅暂停当前线程。 --- #### **3. `CountDownLatch`** ```java public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { int threadCount = 3; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { try { System.out.println("线程执行任务"); Thread.sleep(1000); // 模拟任务耗时 } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); // 任务完成,计数器减1 } }).start(); } latch.await(); // 等待所有线程完成 System.out.println("所有线程任务完成"); } } ``` - **特点**: - 适用于**多线程协作**(如并发测试、分阶段任务)。 - 通过`countDown()`减少计数器,通过`await()`阻塞等待计数器归零。 --- ### **核心区别总结** 1. **线程协作 vs 单线程控制** - `join()`:线程间**一对一等待**(A等B)。 - `sleep()`:**单线程暂停**,不涉及协作。 - `CountDownLatch`:**多线程协作**(A等B、C、D全部完成)。 2. **灵活性** - `join()`和`sleep()`功能单一,`CountDownLatch`支持复杂同步场景(如并发测试起跑线、资源初始化等待)。 3. **性能影响** - `sleep()`不释放资源,可能导致资源占用; - `CountDownLatch`基于AQS,性能更优且支持并发控制。 --- ### **选择建议** - **顺序执行**:使用`join()`(如主线程等待子线程)。 - **定时延迟**:使用`sleep()`(如定时任务、重试机制)。 - **多线程协作**:使用`CountDownLatch`(如并发测试、批量任务完成通知)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值