pda设备 发表于 2025-2-7 00:31:23

多线程开发常见问题汇总

1. Thread.UncaughtExceptionHandler

UncaughtExceptionHandler‌是一个接口,用于处理线程因未捕获异常而突然终止的情况。
虽然,通常都会在线程执行的代码中加try...catch来捕获异常,那么如果某些异常没有被catch住(比如,线程突然死掉了)那么我们将不知道发生了什么。因此,给每个现在设置一个未捕获异常处理器很有必要。
@Slf4jpublic 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 permitsemaphore.acquire();// or acquire 10 permitssemaphore.acquire(10);// or try to acquire permitboolean res = semaphore.tryAcquire();// or try to acquire permit or wait up to 15 secondsboolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS);// or try to acquire 10 permitboolean res = semaphore.tryAcquire(10);// or try to acquire 10 permits or wait up to 15 secondsboolean 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 downlatch.await();// in other thread or JVMRCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");latch.countDown(); 
参考
https://blog.csdn.net/weixin_42373241/article/details/139441473 
  
 
页: [1]
查看完整版本: 多线程开发常见问题汇总