今天复习多线程时发现java处理并发时常用的工具类为CountDownLatch和CyclicBarrier、AtomicInteger
其区别在于CountDownLatch和CyclicBarrier用于线程阻塞,而AtomicInteger用于计数!
CountDownLatch用作减法计数器
/**
* @author zack
* @date 2022/5/11
*/
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
// 总数为6
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"out");
countDownLatch.countDown();
},i+"号线程").start();
}
// 等待计数器归零主线程才结束
countDownLatch.await();
System.out.println("close door");
}
}
1号线程out
4号线程out
3号线程out
2号线程out
5号线程out
6号线程out
close door
Process finished with exit code 0
如果把CountDownLatch的参数改为8的数,那么主线程就会一直阻塞在countDownLatch.await()位置,直到有8个线程执行结束,主线程才会继续执行
1号线程out
4号线程out
2号线程out
3号线程out
6号线程out
5号线程out
CyclicBarrier用作循环阻塞器
/**
* @author zack
* @date 2022/5/11
*/
public class CyclicBarrierDemo {
public static void main(String[] args){
// 总数为7
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("end");
});
for (int i = 1; i <= 7; i++) {
final int temp = i;
new Thread(()->{
System.out.println(Thread.currentThread()
.getName()+" get "+temp);
try {
// 此处线程会被阻塞,等待7个线程执行完毕才执行后面代码
cyclicBarrier.await();
System.out.println(temp+"结束");
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
},i+"号线程").start();
}
System.out.println("主线程结束!!!!!!");
}
}
此用作阻塞单个线程的执行,只有当所定义的7个线程执行完,会先执行创建CyclicBarrier时定义的System.out.println(“end”);再分别(并非依次)执行cyclicBarrier.await();后面的方法。但是主线程并不会等待所有线程执行完就可以提前结束
1号线程 get 1
3号线程 get 3
4号线程 get 4
5号线程 get 5
2号线程 get 2
主线程结束!!!!!!
6号线程 get 6
7号线程 get 7
end
7结束
1结束
4结束
2结束
3结束
6结束
5结束
Process finished with exit code 0
如果CyclicBarrier设置的线程数为8时,所有线程都会一直阻塞在cyclicBarrier.await();位置,直到有8个线程执行结束,才会继续执行
主线程结束!!!!!!
4号线程 get 4
5号线程 get 5
2号线程 get 2
6号线程 get 6
3号线程 get 3
1号线程 get 1
7号线程 get 7
AtomicInteger用于计数
/**
* @author zack
* @date 2022/5/11
*/
public class AtomicIntegerDemo {
public static void main(String[] args) {
// 总数为6
AtomicInteger atomicInteger = new AtomicInteger();
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+
"操作了"+atomicInteger.incrementAndGet());
},i+"号线程").start();
}
System.out.println(atomicInteger.get());
}
}
主线程不会等待所有线程结束就会提前结束,但atomicInteger会返回计数值
1号线程操作了1
5号线程操作了5
4
6号线程操作了4
3号线程操作了3
2号线程操作了2
7号线程操作了7
4号线程操作了6
8号线程操作了8
Process finished with exit code 0