在java多线程为了帮助你更好地编程编程并发编程,java辅助工具这是必不可少的。为此,java对我们它提供了一些非常有用的辅助类别,如CountDownLatch,CyclicBarrier、Semaphore和exchanger。接下来,让我们逐一了解这些java辅助工具是java多线程编程的得力助手。
一、CountDownLatch
它是在完成一组在其他线程中执行的操作之前,同步辅助类允许一个或多个线程等待。其机制是:当多个线程达到预期状态或完成预期工作时触发事件时(具体数量等于初始化CountDownlatch时的Count参数值),其他线程可以等待事件触发其后续工作。需要注意的是,等待的线程可以是多个,即CountDownlatch可以唤醒多个等待的线程。达到预期状态的线程将调用countdownlatch的countdown方法,等待的线程将调用countdownlatch的await方法。
CountDownLatch 将任务分成n个独立部分是非常合适的,等这些部分完成后再继续下一个任务,CountDownLatch 只能出发一次,计数值不能重置。
代码实现:
public class Testcutdownlatch {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(3);
new Thread(new Runnable() {
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Waiter Released");
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
Thread.sleep(1000);
latch.countDown();
Thread.sleep(1000);
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
输出结果:
Waiter Released
二、cyclicbarrier
它您可以协调多个线程,让多个线程在屏障前等待,直到所有线程都达到屏障,然后继续执行以下动作。
Cyclicbarrier适用于多个线程。有固定的多步需要执行。线程相互等待。当所有执行完成后,我们将共同执行下一步。因为 barrier 它可以在释放等待线程后重用,因此被称为循环 的 barrier
代码实现:
public class Testcyclicbarrier {
public static void main(String[] args) {
final CyclicBarrier barrier1 = new CyclicBarrier(2, new Runnable() {
public void run() {
System.out.println("BarrierAction 1 executed ");
}
});
final CyclicBarrier barrier2 = new CyclicBarrier(2, new Runnable() {
public void run() {
System.out.println("BarrierAction 2 executed ");
}
});
for (int i=0;i<3;i++)
{
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"waited barrier1");
barrier1.await();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"waited barrier2");
barrier2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
输出结果:
Thread-0waited barrier1
Thread-2waited barrier1
Thread-1waited barrier1
BarrierAction 1 executed
Thread-0waited barrier2
Thread-1waited barrier2
BarrierAction 2 executed
三、Exchanger
Exchanger类促进了两个共同操作线程之间的双向交换;这样,就像计数一样 2 CyclicBarier,当两个线程都到达屏障时,可以“交换”有些状态。(Exchanger模式有时也叫聚集。)
Exchanger通常用于线程填充缓冲(通过读取) socket),另一个线程清空缓冲(通过处理) socket 收到的命令)。当两个线程集合在屏障处时,它们交换缓冲。
代码实现:
public class Testexchanger {
public static void main(String[]args){
final Exchanger exchanger = new Exchanger();
//Action action=new Action();
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
exchanger.exchange(Thread.currentThread().getName()+"data");
System.out.println(Thread.currentThread().getName()+"我交给你了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
exchanger.exchange(Thread.currentThread().getName()+"data");
System.out.println(Thread.currentThread().getName()+"我交给你了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
输出结果:
Thread-0我交给你了
Thread-1我交给你了
四、Semaphore
Semaphore 管理信号量对象的信号就像令牌,构造时输入数量,总数控制并发数量。我们需要控制并发代码,在执行前获取信号(通过acquire获取信号许可证),并在执行后返回信号(通过release返回信号许可证)。每次成功返回acquire后,semaphore可用的信号量就会减少一个,如果没有可用的信号,acquire调用就会被阻塞,等待release调用释放信号后,acquire才会得到信号并返回。
如果如果Semaphore管理的信号量为1,则退化为相互排斥锁;如果信号量超过一个,则主要用于控制并发数。与通过控制线程数控制并发数相比,通过Semaphore控制并发数可以控制更细的粒度,因为真正控制的最大并发代码可以放在acquire和release之间。
代码实现:
public class Testsemophore {
public static void main(String[]args){
final Semaphore semaphore = new Semaphore(3);
for (int i=0;i<7;i++)
{
new Thread(new Runnable() {
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"获取到许可");
Thread.sleep(1000);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
输出结果:
Thread-0获取到许可
Thread-2获取到许可
Thread-1获取到许可
Thread-3获取到许可
Thread-4获取到许可
Thread-5获取到许可
Thread-6获取到许可
事实上,这些java辅助工具并不像那些无私奉献的人。实现别人,默默做自己。“春蚕直到死丝方尽,蜡炬成灰泪开始干燥。”相信在java多线程工具的帮助下,我们可以让java多线程编程更加规范合理,不断创造新的编程世界奇迹。