一.CountDownLatch用法
CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了
CountDownLatch类只提供了一个构造器:
//参数count为计数值
public CountDownLatch(int count) { };
CountDownLatch类核心方法:
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };
二.CyclicBarrier用法
CyclicBarrier类位于java.util.concurrent包下,意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。CyclicBarrier可以被重用。
CyclicBarrier的构造方法:
//参数parties指让多少个线程或者任务等待至barrier状态
//参数barrierAction为当这些线程都达到barrier状态时会执行的内容。
public CyclicBarrier(int parties, Runnable barrierAction) {}
public CyclicBarrier(int parties) {}
CyclicBarrier核心方法:
//比较常用,用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务
public int await() throws InterruptedException, BrokenBarrierException { };
//让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };
三.Semaphore用法
Semaphore类位于java.util.concurrent包下,可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
Semaphore构造器:
//参数permits表示许可数目,即同时可以允许多少线程进行访问
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
//这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可
public Semaphore(int permits, boolean fair) {
sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}
Semaphore核心方法:
//获取一个许可
public void acquire() throws InterruptedException { }
//获取permits个许可
public void acquire(int permits) throws InterruptedException { }
//释放一个许可
public void release() { }
//释放permits个许可
public void release(int permits) { }
acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。
release()用来释放许可。注意,在释放许可之前,必须先获获得许可。
这4个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法:
//尝试获取一个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire() { };
//尝试获取一个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { };
//尝试获取permits个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(int permits) { };
//尝试获取permits个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { };
对前两个工具的使用代码例子:
创建100个线程同时向一个账户存钱100元
1、Account(账户类)
package test;
public class Account {
private volatile double balance;
public synchronized void addMoney(double money){
System.out.println(Thread.currentThread().getName()+"存钱");
double newBalance = balance + money;
this.balance = newBalance;
System.out.println("当前余额为:"+getBalance());
}
public double getBalance(){
return this.balance;
}
}
2、MoneyThread线程任务执行类
public class MoneyThread extends Thread {
private Account account;
private double money;
private CyclicBarrier cyclicBarrier;
private CountDownLatch count;
public MoneyThread(Account account, double money,CyclicBarrier cyclicBarrier,CountDownLatch count) {
this.account = account;
this.money = money;
this.cyclicBarrier = cyclicBarrier;
this.count = count;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"进入");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
account.addMoney(money);
count.countDown();
System.out.println(Thread.currentThread().getName()+"完成");
}
}
3、main方法调用
public static void main(String[] args) {
System.out.println("********************************************");
long start = System.currentTimeMillis();
Account account = new Account();
CyclicBarrier barrier = new CyclicBarrier(100);
CountDownLatch count = new CountDownLatch(100);
try {
for(int i = 0;i<100;i++){
new MoneyThread(account,100,barrier,count).start();
}
System.out.println("等待100子线程执行....");
count.await();
System.out.println("100个子线程执行完毕");
System.out.println("该账户总余额为:"+account.getBalance());
long end = System.currentTimeMillis();
System.out.println("存钱一共消耗"+(end-start)+"毫秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("********************************************");
}
4、运行结果
********************************************
Thread-0进入
Thread-1进入
Thread-2进入
Thread-3进入
Thread-5进入
Thread-4进入
Thread-6进入
Thread-7进入
Thread-8进入
Thread-9进入
Thread-10进入
Thread-11进入
Thread-13进入
Thread-14进入
Thread-12进入
Thread-16进入
Thread-15进入
Thread-17进入
Thread-18进入
Thread-19进入
Thread-20进入
Thread-21进入
Thread-22进入
Thread-23进入
Thread-25进入
Thread-24进入
Thread-26进入
Thread-28进入
Thread-27进入
Thread-29进入
Thread-30进入
Thread-33进入
Thread-34进入
Thread-32进入
Thread-36进入
Thread-40进入
Thread-31进入
Thread-35进入
Thread-39进入
Thread-50进入
Thread-44进入
Thread-37进入
Thread-41进入
Thread-54进入
Thread-46进入
Thread-59进入
Thread-61进入
Thread-62进入
Thread-63进入
Thread-64进入
Thread-65进入
Thread-66进入
Thread-67进入
Thread-68进入
Thread-69进入
Thread-55进入
Thread-70进入
Thread-53进入
Thread-72进入
Thread-71进入
Thread-73进入
Thread-57进入
Thread-74进入
Thread-49进入
Thread-75进入
Thread-58进入
Thread-76进入
Thread-77进入
Thread-78进入
Thread-56进入
Thread-79进入
Thread-45进入
Thread-80进入
Thread-52进入
Thread-81进入
Thread-82进入
Thread-84进入
Thread-85进入
Thread-86进入
Thread-83进入
Thread-87进入
Thread-51进入
Thread-88进入
Thread-89进入
Thread-90进入
Thread-91进入
Thread-93进入
Thread-94进入
Thread-92进入
Thread-95进入
Thread-42进入
Thread-97进入
等待100子线程执行....
Thread-98进入
Thread-96进入
Thread-47进入
Thread-43进入
Thread-60进入
Thread-99进入
Thread-38进入
Thread-48进入
Thread-48存钱
当前余额为:100.0
Thread-2存钱
当前余额为:200.0
Thread-2完成
Thread-48完成
Thread-5存钱
当前余额为:300.0
Thread-5完成
Thread-4存钱
当前余额为:400.0
Thread-4完成
Thread-3存钱
当前余额为:500.0
Thread-3完成
Thread-0存钱
当前余额为:600.0
Thread-0完成
Thread-8存钱
当前余额为:700.0
Thread-8完成
Thread-1存钱
当前余额为:800.0
Thread-1完成
Thread-9存钱
当前余额为:900.0
Thread-9完成
Thread-10存钱
当前余额为:1000.0
Thread-10完成
Thread-7存钱
当前余额为:1100.0
Thread-7完成
Thread-6存钱
当前余额为:1200.0
Thread-6完成
Thread-11存钱
当前余额为:1300.0
Thread-11完成
Thread-13存钱
当前余额为:1400.0
Thread-13完成
Thread-14存钱
当前余额为:1500.0
Thread-14完成
Thread-12存钱
当前余额为:1600.0
Thread-12完成
Thread-16存钱
当前余额为:1700.0
Thread-16完成
Thread-15存钱
当前余额为:1800.0
Thread-15完成
Thread-17存钱
当前余额为:1900.0
Thread-17完成
Thread-18存钱
当前余额为:2000.0
Thread-18完成
Thread-19存钱
当前余额为:2100.0
Thread-19完成
Thread-20存钱
当前余额为:2200.0
Thread-20完成
Thread-21存钱
当前余额为:2300.0
Thread-21完成
Thread-22存钱
当前余额为:2400.0
Thread-22完成
Thread-23存钱
当前余额为:2500.0
Thread-23完成
Thread-25存钱
当前余额为:2600.0
Thread-25完成
Thread-24存钱
当前余额为:2700.0
Thread-24完成
Thread-28存钱
当前余额为:2800.0
Thread-28完成
Thread-26存钱
当前余额为:2900.0
Thread-26完成
Thread-29存钱
当前余额为:3000.0
Thread-29完成
Thread-30存钱
当前余额为:3100.0
Thread-30完成
Thread-33存钱
当前余额为:3200.0
Thread-33完成
Thread-34存钱
当前余额为:3300.0
Thread-34完成
Thread-32存钱
当前余额为:3400.0
Thread-32完成
Thread-36存钱
当前余额为:3500.0
Thread-36完成
Thread-27存钱
当前余额为:3600.0
Thread-27完成
Thread-40存钱
当前余额为:3700.0
Thread-40完成
Thread-35存钱
当前余额为:3800.0
Thread-35完成
Thread-50存钱
当前余额为:3900.0
Thread-50完成
Thread-31存钱
当前余额为:4000.0
Thread-31完成
Thread-39存钱
当前余额为:4100.0
Thread-39完成
Thread-44存钱
当前余额为:4200.0
Thread-44完成
Thread-37存钱
当前余额为:4300.0
Thread-37完成
Thread-41存钱
当前余额为:4400.0
Thread-41完成
Thread-54存钱
当前余额为:4500.0
Thread-54完成
Thread-46存钱
当前余额为:4600.0
Thread-46完成
Thread-59存钱
当前余额为:4700.0
Thread-59完成
Thread-61存钱
当前余额为:4800.0
Thread-61完成
Thread-62存钱
当前余额为:4900.0
Thread-62完成
Thread-63存钱
当前余额为:5000.0
Thread-63完成
Thread-64存钱
当前余额为:5100.0
Thread-64完成
Thread-65存钱
当前余额为:5200.0
Thread-65完成
Thread-66存钱
当前余额为:5300.0
Thread-66完成
Thread-67存钱
当前余额为:5400.0
Thread-67完成
Thread-68存钱
当前余额为:5500.0
Thread-68完成
Thread-69存钱
当前余额为:5600.0
Thread-69完成
Thread-55存钱
当前余额为:5700.0
Thread-55完成
Thread-70存钱
当前余额为:5800.0
Thread-70完成
Thread-53存钱
当前余额为:5900.0
Thread-53完成
Thread-73存钱
当前余额为:6000.0
Thread-73完成
Thread-71存钱
当前余额为:6100.0
Thread-71完成
Thread-72存钱
当前余额为:6200.0
Thread-72完成
Thread-49存钱
当前余额为:6300.0
Thread-49完成
Thread-74存钱
当前余额为:6400.0
Thread-74完成
Thread-57存钱
当前余额为:6500.0
Thread-57完成
Thread-58存钱
当前余额为:6600.0
Thread-58完成
Thread-76存钱
当前余额为:6700.0
Thread-76完成
Thread-75存钱
当前余额为:6800.0
Thread-75完成
Thread-45存钱
当前余额为:6900.0
Thread-45完成
Thread-80存钱
当前余额为:7000.0
Thread-80完成
Thread-84存钱
当前余额为:7100.0
Thread-84完成
Thread-86存钱
当前余额为:7200.0
Thread-86完成
Thread-83存钱
当前余额为:7300.0
Thread-83完成
Thread-79存钱
当前余额为:7400.0
Thread-79完成
Thread-56存钱
当前余额为:7500.0
Thread-56完成
Thread-78存钱
当前余额为:7600.0
Thread-78完成
Thread-77存钱
当前余额为:7700.0
Thread-77完成
Thread-87存钱
当前余额为:7800.0
Thread-87完成
Thread-85存钱
当前余额为:7900.0
Thread-85完成
Thread-82存钱
当前余额为:8000.0
Thread-82完成
Thread-81存钱
当前余额为:8100.0
Thread-81完成
Thread-92存钱
当前余额为:8200.0
Thread-92完成
Thread-52存钱
当前余额为:8300.0
Thread-52完成
Thread-47存钱
当前余额为:8400.0
Thread-47完成
Thread-89存钱
当前余额为:8500.0
Thread-90存钱
当前余额为:8600.0
Thread-90完成
Thread-89完成
Thread-43存钱
当前余额为:8700.0
Thread-43完成
Thread-96存钱
当前余额为:8800.0
Thread-96完成
Thread-98存钱
当前余额为:8900.0
Thread-98完成
Thread-99存钱
当前余额为:9000.0
Thread-99完成
Thread-38存钱
当前余额为:9100.0
Thread-38完成
Thread-97存钱
当前余额为:9200.0
Thread-97完成
Thread-42存钱
当前余额为:9300.0
Thread-42完成
Thread-95存钱
当前余额为:9400.0
Thread-95完成
Thread-94存钱
当前余额为:9500.0
Thread-94完成
Thread-93存钱
当前余额为:9600.0
Thread-93完成
Thread-88存钱
当前余额为:9700.0
Thread-88完成
Thread-91存钱
当前余额为:9800.0
Thread-91完成
Thread-51存钱
当前余额为:9900.0
Thread-51完成
Thread-60存钱
当前余额为:10000.0
Thread-60完成
100个子线程执行完毕
该账户总余额为:10000.0
存钱一共消耗111毫秒
********************************************