1.CountDownLatch (线程计数器)
利用CountDownLatch 可以实现类似计数器的功能,比如主线程需要等待5个子线程执行完毕之后才能执行,就可以利用CountDownLatch实现,案例如下:
public class TestThread {
final static CountDownLatch latch = new CountDownLatch(5); //如果大于num将会造成一直等待
public static void main(String[] args) throws InterruptedException {
//线程数
int num = 5;
MyRunnable myRunnable = new MyRunnable();
for(int i=0;i<5;i++){
new Thread(myRunnable).start();
}
latch.await();
System.out.println("主线程了");
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"我是run方法");
TestThread.latch.countDown();
}
}
执行结果:
2.CyclicBarrier(回环栅栏)
回环栅栏的作用就是整合一组线程,在这一组线程全部达到某个状态之后同时执行,其最重要的方法为await()
1. public int await():用来挂起当前线程,直至所有线程都到达 barrier 状态再同时执行后续任
务;
2. public int await(long timeout, TimeUnit unit):让这些线程等待至一定的时间,如果还有
线程没有到达 barrier 状态就直接让到达 barrier 的线程执行后续任务。
案例:
public class TestThread {
public static void main(String[] args) throws InterruptedException {
//线程数
int num = 5;
CyclicBarrier cb = new CyclicBarrier(5); //如果大于num将会造成一直等待
MyRunnable myRunnable = new MyRunnable(cb);
for(int i=0;i<num;i++){
new Thread(myRunnable).start();
}
}
}
class MyRunnable implements Runnable{
private CyclicBarrier cb;
public MyRunnable(){}
public MyRunnable(CyclicBarrier cb){
this.cb = cb;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("业务代码操作完成,等待其他线程执行完毕");
cb.await();
System.out.println("所有线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
执行结果:
3.Semaphore(信号量)
Semaphore可以控制同时访问的线程个数,通过acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
案例:
public class TestThread {
final static int S_NUM = 1;
final static Semaphore SP = new Semaphore(S_NUM);
public static void main(String[] args) throws InterruptedException {
//线程数
int num = 5;
MyRunnable myRunnable = new MyRunnable();
for(int i=0;i<num;i++){
new Thread(myRunnable).start();
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
try {
TestThread.SP.acquire();
System.out.println(Thread.currentThread().getName()+"在执行start");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"在执行end");
TestThread.SP.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果(S_NUM=1时):
执行结果(S_NUM=2时):
由S_NUM=2可以看出Semaphore可以控制线程同时执行数量。