多线程开发常见题目汇总

打印 上一主题 下一主题

主题 862|帖子 862|积分 2586

1. Thread.UncaughtExceptionHandler

UncaughtExceptionHandler‌是一个接口,用于处置惩罚线程因未捕获异常而突然终止的情况。
固然,通常都会在线程实行的代码中加try...catch来捕获异常,那么假如某些异常没有被catch住(比如,线程突然死掉了)那么我们将不知道发生了什么。因此,给每个现在设置一个未捕获异常处置惩罚器很有必要。
  1. @Slf4j
  2. public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
  3.     @Override
  4.     public void uncaughtException(Thread t, Throwable e) {
  5.         log.info("线程异常: {}", t.getName(), e);
  6.     }
  7. }
  8. public static void main(String[] args) {
  9.     //  设置全局默认的未捕获异常处理器
  10.     Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
  11.     Thread thread = new Thread(() -> {
  12.         int a = 1 / 0;
  13.     });
  14.     //  给某个线程设置自己的未捕获异常处理器
  15.     thread.setUncaughtExceptionHandler(((t, e) -> {
  16.         System.out.println("线程执行异常!线程名称: " + t.getName());
  17.         logger.error("线程执行异常!名称: {}", t.getName(), e);
  18.     }));
  19.     thread.start();
  20. }
复制代码
通常我们采用线程池的方式使用线程,下面是在线程池中使用方式
  1. public static void main(String[] args) {
  2.     ExecutorService executorService = Executors.newFixedThreadPool(3, new ThreadFactory() {
  3.         @Override
  4.         public Thread newThread(Runnable r) {
  5.             Thread t = new Thread(r);
  6.             t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
  7.             return t;
  8.         }
  9.     });
  10.     executorService.execute(new Runnable() {
  11.         @Override
  12.         public void run() {
  13.             int a = 1 / 0;
  14.         }
  15.     });
  16. }
复制代码
2. CountDownLatch(倒计时)

CountDownLatch 是 Java 中的一个同步工具类,它答应一个或多个线程等待其他线程完成操作。
  1. public static void main(String[] args) {
  2.     ExecutorService executorService = Executors.newFixedThreadPool(3, new ThreadFactory() {
  3.         @Override
  4.         public Thread newThread(Runnable r) {
  5.             Thread t = new Thread(r);
  6.             t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
  7.             return t;
  8.         }
  9.     });
  10.     int count = 10; //  10个任务
  11.     CountDownLatch latch = new CountDownLatch(count);
  12.     for (int i = 0; i < count; i++) {
  13. //            executorService.execute(()->{
  14. //                try {
  15. //
  16. //                } catch (Exception ex) {
  17. //
  18. //                } finally {
  19. //                    latch.countDown();
  20. //                }
  21. //
  22. //            });
  23.         executorService.execute(new MyTask(latch));
  24.     }
  25.     try {
  26.         latch.await();  //  等待所有异步任务执行完成
  27.     } catch (InterruptedException e) {
  28.         throw new RuntimeException(e);
  29.     }
  30.     //  执行后续处理逻辑
  31. }
  32. static class MyTask implements Runnable {
  33.     private CountDownLatch latch;
  34.     public MyTask(CountDownLatch latch) {
  35.         this.latch = latch;
  36.     }
  37.     @Override
  38.     public void run() {
  39.         try {
  40.         } catch (Exception e) {
  41.         } finally {
  42.             latch.countDown();
  43.         }
  44.     }
  45. }
复制代码
3. Semaphore(信号量)

Semaphore 是一个用于控制同时访问特定资源的线程数量的同步工具。它通过维护一个答应集来管理对资源的访问。线程在访问资源之前必须从信号量中获取答应,访问完成后释放答应。假如没有可用的答应,线程将被阻塞,直到有可用的答应为止。
  1. /**
  2. * 控制并发执行的任务数量
  3. */
  4. public static void main(String[] args) {
  5.     ExecutorService executorService = Executors.newFixedThreadPool(3);
  6.     Semaphore semaphore = new Semaphore(10);
  7.     //  模拟100个附件同时上传
  8.     for (int i = 0; i < 100; i++) {
  9.         executorService.execute(()->{
  10.             try {
  11.                 semaphore.acquire();
  12.                 upload();
  13.             } catch (Exception e) {
  14.             } finally {
  15.                 semaphore.release();
  16.             }
  17.         });
  18.     }
  19.    
  20.     executorService.shutdown();
  21. }
  22. /**
  23. * 附件上传操作
  24. */
  25. public static void upload() {
  26.     //  假设,最多同时处理10个附件,太多的话可能会内存溢出,为了保护它,不让它挂掉,我们可以控制并发请求数量
  27.     //  ......
  28. }
复制代码
上面的例子,我们在调用端限制并发请求数来达到掩护被调用方的目的,其实也可以写在被调用端,效果是一样的,在调用方和被调用方其中一方做控制就行。
4. Redisson分布式锁和同步器

Redisson 是 Redis 的Java客户端,在分布式环境下,Redission实现了Semaphore和CountDownLatch。
https://redisson.org/docs/data-and-services/locks-and-synchronizers/

  1. <dependency>
  2.     <groupId>org.redisson</groupId>
  3.     <artifactId>redisson</artifactId>
  4.     <version>3.41.0</version>
  5. </dependency>
复制代码
Semaphore根本用法
  1. RSemaphore semaphore = redisson.getSemaphore("mySemaphore");
  2. // acquire single permit
  3. semaphore.acquire();
  4. // or acquire 10 permits
  5. semaphore.acquire(10);
  6. // or try to acquire permit
  7. boolean res = semaphore.tryAcquire();
  8. // or try to acquire permit or wait up to 15 seconds
  9. boolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS);
  10. // or try to acquire 10 permit
  11. boolean res = semaphore.tryAcquire(10);
  12. // or try to acquire 10 permits or wait up to 15 seconds
  13. boolean res = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
  14. if (res) {
  15.    try {
  16.      ...
  17.    } finally {
  18.        semaphore.release();
  19.    }
  20. }
复制代码
CountDownLatch根本用法
  1. RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
  2. latch.trySetCount(1);
  3. // await for count down
  4. latch.await();
  5. // in other thread or JVM
  6. RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
  7. latch.countDown();
复制代码
 
参考
https://blog.csdn.net/weixin_42373241/article/details/139441473 
  
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户国营

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表