1. Thread.UncaughtExceptionHandler
UncaughtExceptionHandler是一个接口,用于处置惩罚线程因未捕获异常而突然终止的情况。
固然,通常都会在线程实行的代码中加try...catch来捕获异常,那么假如某些异常没有被catch住(比如,线程突然死掉了)那么我们将不知道发生了什么。因此,给每个现在设置一个未捕获异常处置惩罚器很有必要。- @Slf4j
- public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- log.info("线程异常: {}", t.getName(), e);
- }
- }
- public static void main(String[] args) {
- // 设置全局默认的未捕获异常处理器
- Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
- Thread thread = new Thread(() -> {
- int a = 1 / 0;
- });
- // 给某个线程设置自己的未捕获异常处理器
- thread.setUncaughtExceptionHandler(((t, e) -> {
- System.out.println("线程执行异常!线程名称: " + t.getName());
- logger.error("线程执行异常!名称: {}", t.getName(), e);
- }));
- thread.start();
- }
复制代码 通常我们采用线程池的方式使用线程,下面是在线程池中使用方式- public static void main(String[] args) {
- ExecutorService executorService = Executors.newFixedThreadPool(3, new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
- return t;
- }
- });
- executorService.execute(new Runnable() {
- @Override
- public void run() {
- int a = 1 / 0;
- }
- });
- }
复制代码 2. CountDownLatch(倒计时)
CountDownLatch 是 Java 中的一个同步工具类,它答应一个或多个线程等待其他线程完成操作。- public static void main(String[] args) {
- ExecutorService executorService = Executors.newFixedThreadPool(3, new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
- return t;
- }
- });
- int count = 10; // 10个任务
- CountDownLatch latch = new CountDownLatch(count);
- for (int i = 0; i < count; i++) {
- // executorService.execute(()->{
- // try {
- //
- // } catch (Exception ex) {
- //
- // } finally {
- // latch.countDown();
- // }
- //
- // });
- executorService.execute(new MyTask(latch));
- }
- try {
- latch.await(); // 等待所有异步任务执行完成
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- // 执行后续处理逻辑
- }
- static class MyTask implements Runnable {
- private CountDownLatch latch;
- public MyTask(CountDownLatch latch) {
- this.latch = latch;
- }
- @Override
- public void run() {
- try {
- } catch (Exception e) {
- } finally {
- latch.countDown();
- }
- }
- }
复制代码 3. Semaphore(信号量)
Semaphore 是一个用于控制同时访问特定资源的线程数量的同步工具。它通过维护一个答应集来管理对资源的访问。线程在访问资源之前必须从信号量中获取答应,访问完成后释放答应。假如没有可用的答应,线程将被阻塞,直到有可用的答应为止。- /**
- * 控制并发执行的任务数量
- */
- public static void main(String[] args) {
- ExecutorService executorService = Executors.newFixedThreadPool(3);
- Semaphore semaphore = new Semaphore(10);
- // 模拟100个附件同时上传
- for (int i = 0; i < 100; i++) {
- executorService.execute(()->{
- try {
- semaphore.acquire();
- upload();
- } catch (Exception e) {
- } finally {
- semaphore.release();
- }
- });
- }
-
- executorService.shutdown();
- }
- /**
- * 附件上传操作
- */
- public static void upload() {
- // 假设,最多同时处理10个附件,太多的话可能会内存溢出,为了保护它,不让它挂掉,我们可以控制并发请求数量
- // ......
- }
复制代码 上面的例子,我们在调用端限制并发请求数来达到掩护被调用方的目的,其实也可以写在被调用端,效果是一样的,在调用方和被调用方其中一方做控制就行。
4. Redisson分布式锁和同步器
Redisson 是 Redis 的Java客户端,在分布式环境下,Redission实现了Semaphore和CountDownLatch。
https://redisson.org/docs/data-and-services/locks-and-synchronizers/
- <dependency>
- <groupId>org.redisson</groupId>
- <artifactId>redisson</artifactId>
- <version>3.41.0</version>
- </dependency>
复制代码 Semaphore根本用法- RSemaphore semaphore = redisson.getSemaphore("mySemaphore");
- // acquire single permit
- semaphore.acquire();
- // or acquire 10 permits
- semaphore.acquire(10);
- // or try to acquire permit
- boolean res = semaphore.tryAcquire();
- // or try to acquire permit or wait up to 15 seconds
- boolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS);
- // or try to acquire 10 permit
- boolean res = semaphore.tryAcquire(10);
- // or try to acquire 10 permits or wait up to 15 seconds
- boolean res = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
- if (res) {
- try {
- ...
- } finally {
- semaphore.release();
- }
- }
复制代码 CountDownLatch根本用法- RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
- latch.trySetCount(1);
- // await for count down
- latch.await();
- // in other thread or JVM
- RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
- latch.countDown();
复制代码
参考
https://blog.csdn.net/weixin_42373241/article/details/139441473
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |