Exchanger 让两个线程在一个汇合点互换对象,典型用法是一个线程填满缓冲区、另一个线程消费空缓冲区。这篇真实运行它的交换、超时中断、多线程配对,并与阻塞队列对比传输开销。
主线程拿到「来自子线程」,子线程拿到「来自主线程」;子线程先到,等了 210 ms(约等于主线程晚到的 200 ms),交换完成后两边同时返回 exchange(null) 是允许的:对方传 null,这边得到 null;反过来对方得到「x」 交换的是引用不是内容:主线程送出数组 A,拿回 B(true),子线程拿到 A(true),没有复制;之后两边各自独占一个数组,A 的内容仍是 [1, 2, 3]
没有伙伴:exchange(x, 300ms) → TimeoutException,耗时 306 ms 超时之后同一个 Exchanger 仍可用:主线程拿到「子线程的值」,子线程拿到「主线程的值」 等待中的线程被中断 → InterruptedException;之后换一对线程交换:主线程得到 B,子线程得到 A 伙伴晚到 400 ms,而超时 100 ms → TimeoutException(先到的一方放弃,不会被晚到的伙伴补上)
4 个线程(T0 先到,依次间隔 20 ms)共用一个 Exchanger,每个线程的结果:{T0=T1, T1=T0, T2=T3, T3=T2}
5 个线程(T0 先到,依次间隔 20 ms)共用一个 Exchanger,每个线程的结果:{T0=T1, T1=T0, T2=T3, T3=T2, T4=(超时,没有伙伴)}
4 个线程同时开始,重复 30 次,出现过的配对方式:[0↔1 2↔3, 0↔3 1↔2](同时到达时谁和谁配对不固定)Exchanger 交换 1024 元素的缓冲区:消费方求和 = 71680000(期望 71680000) 第 1 轮,传 20480000 个 int:Exchanger 换缓冲区 56 ms;ArrayBlockingQueue 传缓冲区(回收池)65 ms;LinkedBlockingQueue 逐个传 2015 ms 第 2 轮,传 20480000 个 int:Exchanger 换缓冲区 16 ms;ArrayBlockingQueue 传缓冲区(回收池)69 ms;LinkedBlockingQueue 逐个传 1899 ms 第 3 轮,传 20480000 个 int:Exchanger 换缓冲区 54 ms;ArrayBlockingQueue 传缓冲区(回收池)62 ms;LinkedBlockingQueue 逐个传 2000 ms 第 4 轮,传 20480000 个 int:Exchanger 换缓冲区 13 ms;ArrayBlockingQueue 传缓冲区(回收池)68 ms;LinkedBlockingQueue 逐个传 1688 ms