并发技术_2_Exchanger

本文详细介绍了Java并发工具类Exchanger的使用方法,包括基本概念、线程间的同步数据交换、阻塞特性及超时处理等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Exchanger

 

Exchanger的功能可以使2个线程之间传输数据,它比生产者/消费者模式使用的wait/notify要更加方便。

 

Exchanger(交换者)是一个用于线程间协作的工具类。它用于线程间的数据交换。

如果第一个线程先执行了exchanger方法,它会一直等待第二个线程也执行exchanger,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程产生的数据传递给对象。

 


第一个Demo

public class ExhcangerTest {

	private static final Exchanger<String> exgr = new Exchanger<String>();

	// 创建固定大小的线程池
	private static ExecutorService threadPool = Executors.newFixedThreadPool(2);

	public static void main(String[] args) {

	threadPool.execute(new Runnable() {

	@Override
	public void run() {
			try {
					String A = "银行流水A";
					System.out.println("A先睡一会");
					TimeUnit.SECONDS.sleep(5);
					System.out.println("A : " + exgr.exchange(A));
			} catch (Exception e) {
					e.printStackTrace();
			}
	}
	});

	threadPool.execute(new Runnable() {

	@Override
	public void run() {
			try {
					String B = "银行流水B";
					System.out.println("B准备好了");
					System.out.println("B : " + exgr.exchange(B));
			} catch (Exception e) {
					e.printStackTrace();
			}
	}
	});

	threadPool.shutdown();

	}

}

输出结果:
	A先睡一会
	B准备好了
	A : 银行流水B
	B : 银行流水A
	

这个Demo可以看出,如果两个线程有一个线程没有到达exchange方法,则会一直等待下去,如果担心有特殊情况,想避免一直等待,

可以使用exchange(V x , long timeout , TimeUnit unit)设置最长等待时间。

 


 

方法exchange()阻塞的特性

Exchanger中的exchange()方法具有阻塞的特点,也就是此方法被调用后等待其他线程来读取数据,如果没有线程来读取数据,则一直阻塞下去。

 

我们通过一个Demo,来看下线程阻塞效果:

public class ThreadA extends Thread {

	private Exchanger<String> exchanger;

	public ThreadA(Exchanger<String> exchanger) {
			this.exchanger = exchanger;
	}

	@Override
	public void run() {

	try {

	System.out.println("在线程A中得到线程B的值 = " + exchanger.exchange("中国人A"));
	System.out.println("A end");

	} catch (Exception e) {
			e.printStackTrace();
	}

	}

}

public class Run {

	public static void main(String[] args) {

	Exchanger<String> exchanger = new Exchanger<String>();
	ThreadA a = new ThreadA(exchanger);
	a.start();
	System.out.println("main end");

	}

}

输出结果:


可以看出,虽然main运行完毕,但ThreadA一直在线程阻塞中。



 

方法exchange()传递数据

ThreadA ThreadB 之间互相传递数据

public class ThreadA extends Thread {

	private Exchanger<String> exchanger;

	public ThreadA(Exchanger<String> exchanger) {
			this.exchanger = exchanger;
	}

	@Override
	public void run() {

	try {

	System.out.println("线程A得到线程B的值 = " + exchanger.exchange("中国人A"));

	} catch (Exception e) {
			e.printStackTrace();
	}

	}

}

public class ThreadB extends Thread {

	private Exchanger<String> exchanger;

	public ThreadB(Exchanger<String> exchanger) {
			this.exchanger = exchanger;
	}

	@Override
	public void run() {

	try {

	System.out.println("线程B得到线程A的值 = " + exchanger.exchange("中国人B"));

	} catch (Exception e) {
			e.printStackTrace();
	}

	}

}


public class Run {

	public static void main(String[] args) {

	Exchanger<String> exchanger = new Exchanger<String>();

	ThreadA a = new ThreadA(exchanger);
	ThreadB b = new ThreadB(exchanger);

	a.start();
	b.start();

	}

}

输出结果:

从输出结果看,线程A与线程B互相传递了数据。

(看的有些云里雾里,后面找资料补全)

 

 


方法exchange(Vx,long timeout,TimeUnit unit)与超时

当调用exchange(V x,longtimeout,TimeUnit unit)方法后,在指定的时间内没有其他线程获取数据,则会出现超时异常。

public class ThreadA extends Thread {

	private Exchanger<String> exchanger;

	public ThreadA(Exchanger<String> exchanger) {
			this.exchanger = exchanger;
	}

	@Override
	public void run() {

	try {

	System.out.println("在线程A中得到线程B的值 = " + exchanger.exchange("中国人A", 5, TimeUnit.SECONDS));

	} catch (Exception e) {
			e.printStackTrace();
	}

	}

}

public class Run {

	public static void main(String[] args) {

	Exchanger<String> exchanger = new Exchanger<String>();
	ThreadA a = new ThreadA(exchanger);
	a.start();
	System.out.println("main end");

	}

}

输出结果:

以上,可以看到,5秒之后,因为没有其他线程调用,抛出超时异常。


小结:

 

Semaphore的主要作用是限制并发执行的线程数量,它具有synchronized所不具备的强大功能,比如:

  1. 等待获取许可的同时加入等待时间
  2. 尝试是否可以持有锁这些扩展功能

 

Exchanger是线程间传输数据的方式之一,而且在传输的数据类型上并没有任何限制。


资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值