ava1.5引入工具类有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
1. countDownLatch
countDownLatch的实现是一个计数器, 作用是使一个线程等待其他线程执行结束后才继续执行。
使用方法, 先设置一个数, 每次减少一, 等减少到0就继续执行
public static void main(String[] args) throws InterruptedException {
//必须要执行任务的时候再使用
CountDownLatch countDownLatch = new CountDownLatch(10);//倒计时 总数是6
for (int i = 1; i <= 10; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName());
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
countDownLatch.await();//等待计数器归零 再向下执行
System.out.println("end--------");
}
3个重要方法
//调用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() { };
2. cyclicBarrier
刚才那个是减少到0, 这个是增加到某个数,引发执行线程,
类似场景是去吃饭时候,等人到3个人才可以去吃饭, 就会等待其他人, 当人数达到3时, 就去吃饭(触发指定线程)
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
System.out.println("去吃饭饭");
});
for (int i = 1; i <= 7; i++) {
final int temp = i;
new Thread(() -> {
System.out.println("有" + temp +"个人在等待" );
try {
// System.out.println("开始等待");
cyclicBarrier.await();
// System.out.println("等待结束");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
3.semaphore
Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数。
场景如下:有6个人去抢位置, 只有3个位置, 这时候,没抢到位置的人要等抢到位置的离开后才能去坐
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); //信号量 3个位置
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
semaphore.acquire();//获取 如果已经满了 就等待
System.out.println(Thread.currentThread().getName() + "抢到位置");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "离开位置");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//释放 唤醒等待的现场的线程
}
}, String.valueOf(i)).start();
}
}
4.BlockingQueue
阻塞队列, 就是指定一个队列的大小,然后放东西进去,队列满了以后,就不能放进去, 要么报错,要么不放, 要么等待。
阻塞队列有4组方法
- 队列满了再继续放进去就报错,移除空了再移除就报错
blockingQueue.add("a")
blockingQueue.remove()
- 队列满了再继续放进去就返回false,移除空了再移除返回null
blockingQueue.offer("a")
blockingQueue.poll()
- 满了就一直等待位置, 空了就一直等待数据
blockingQueue.put("a");
blockingQueue.take();
- 指定等待时间
blockingQueue.offer("a");
blockingQueue.poll();
public static void main(String[] args) throws InterruptedException {
test4();
}
public static void test1() {
//队列的大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
// System.out.println(blockingQueue.add("d"));
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());
}
public static void test2() {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d"));
System.out.println(blockingQueue.element());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
public static void test3() throws InterruptedException { //等待
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
// blockingQueue.put("d");
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());//会一直等待
}
public static void test4() throws InterruptedException { //等待
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.offer("a");
blockingQueue.offer("b");
blockingQueue.offer("c");
blockingQueue.offer("d", 2, TimeUnit.SECONDS); //等待2秒
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));//等待2秒
}