7、Callable()
7.1、Callable 与 Runnable
比较 | Callable | Runnable |
---|---|---|
类型 | 接口 (函数式接口,可用lambda) | 接口 (函数式接口,可用lambda) |
包 | java.util.concurrent | java.lang |
方法 | call() | run() |
返回值 | 有返回值。类型与泛型的类型一致 | 没有返回值。void |
导常 | 可以抛出异常 | 不能抛出被检查的异常 |
7.2、Thread 中使用 Callable
问题
-
Thread 不能直接使用 Callable 的实现类
Thread 构造器中不能接受 Callable 的实现类,但可以接受 Runnable 的实现类
思路
让 Callable 和 Runnable 建立联系,通过 Runnable 做桥梁,让 Thread 可以使用 Callable
8、同步辅助类 (必会)
8.1、CountDownLatch
同步计数器(减法)
原理:
countDownLatch.countDown(); //数量减1
countDownLatch.await();// 等待计数器归零,然后再向下执行
每次有线程调用countDown()数量-1,假设计数器变为0,countDownLatch.await(),就会被唤醒,继续执行
- 示例
厂区门卫
当所有人都离开后,再关门
package auxiliaryClass;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.FutureTask;
/**
* @author ajun
* Date 2021/7/5
* @version 1.0
* 减法计算器
*/
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
//定义计算器
// 倒计时总数是6, 必须要执行任务的时候,再使用!
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(new FutureTask<>(() -> {
System.out.println(Thread.currentThread().getName() + " : 走了!");
countDownLatch.countDown();//计算器减1
return 1000;
}), String.valueOf(i)).start();
}
countDownLatch.await();// 等待计数器归零,然后再向下执行
System.out.println("关门!");
}
}
8.2、CyclicBarrier
同步计数器(加法)
cyclic 循环
barrier 栅栏
- 示例
观光车:每达到5人时发车
package auxiliaryClass;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
/**
* @author ajun
* Date 2021/7/5
* @version 1.0
* 循环栅栏
* 观光车:每达到5人时发车
*/
public class CyclicBarrierDemo {
public static void main(String[] args) throws InterruptedException {
//观光车:每达到5人时发车
CyclicBarrier bus = new CyclicBarrier(5,() -> {System.out.println("可以发车了");});
for (int i = 1; i <= 50; i++) {
TimeUnit.SECONDS.sleep(1);//乘客到来的时间间隔
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 号乘客来了");
try {
bus.await();//等待。达到5人就通知发车,否则就等待。
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
8.3、Semaphore
信号量、信号灯
原理:
semaphore.acquire(); //获取信号量,假设已经满了,等待信号量可用时被唤醒
semaphore.release();//释放信号量
作用:
多个共享资源互斥的使用!
并发限流,控制最大的线程数