N个线程交替打印的另类解法(CompletableFuture)

128 阅读1分钟

最近看一些基础相关的,突然又看到老生常谈的线程交替打印问题,加上工作这么多年多线程玩法不说融会贯通也可以说融会贯通了。针对这个大多数的解法就是加锁和等待唤醒,其实任务是同一个,如果任务异常还需要单独站在全局角度处理,另一种思路就是拆分任务,好处是单个任务的失败不会影响整体,加上最近喜欢玩CompletableFuture刚好里面有个thenRunAsync可以解决交替任务的问题,就试了下,上代码吧。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Description:
 *
 * @author: YC
 * @date: 2023/11/19
 * @param:
 * @return:
 */
public class Test {
   public static void main(String[] args) {
      printAlternately(50, 200);
   }

   private static ExecutorService[] generateExecutors(int n) {
      ExecutorService[] executorServices = new ExecutorService[n];
      for (int i = 0; i < n; i++) {
         int finalI = i;
         executorServices[i] = Executors.newSingleThreadExecutor(runnable -> {
            Thread thread = new Thread(runnable);
            thread.setName("线程" + finalI);
            return thread;
         });
      }
      return executorServices;
   }

   private static void printAlternately(int threadsCounts, int taskCounts) {
      assert threadsCounts > 0;
      assert taskCounts > 0;
      ExecutorService[] executorServices = generateExecutors(threadsCounts);
      int[] taskNum = {0};
      Runnable sout = () -> System.out.println(Thread.currentThread().getName() + ":" + taskNum[0]++);
      CompletableFuture<Void> future = CompletableFuture.runAsync(sout, executorServices[0]);
      for (int i = 1; i < taskCounts; i++) {
         future = future.thenRunAsync(sout, executorServices[i % executorServices.length]);
      }
   }
}

测试了下

image.png