Skip to content

All tasks are executed in the current thread to avoid creating threads.

License

Notifications You must be signed in to change notification settings

blabla-yy/CurrentThreadExecutor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CurrentThreadExecutor

CurrentThreadExecutor是基于Executor接口的实现类。主要用途是避免创建线程,使用已有的单(当前)线程所有执行所有异步任务。 JDK大多API默认使用ForkJoinPool来执行异步任务。而Executors提供的实现都是基于创建线程实现的。在一些场景如需要处理大量IO任务但不想使用多线程,CurrentThreadExecutor是一个更好的选择。

可以用在所有兼容Executor接口的类中,如:CompletableFuture、HttpClient,也可以使多个VirtualThread在一个线程上执行。

使用场景

  • 基于已有的线程(单线程)处理大量异步IO任务,消除线程池配置困扰以及多线程问题,节省资源。
  • 使用CompletableFuture等异步工具,希望任务全部执行在一个已有的线程上 。
  • 使用JDK19+ VirtualThread同样可以指定此Executor,避免使用额外的线程资源。

特点

  • 无创建线程,当前线程处理所有异步任务。
  • 统计累计所有任务耗时。可以用来评估CPU计算耗时和IO耗时的占比。
  • 支持interrupt中断。
  • 超时终止执行。
  • 支持类似Node.js next-tick回调。
  • JDK8+

添加Maven依赖

<dependency>
    <groupId>io.github.blabla-yy</groupId>
    <artifactId>current-thread-executor</artifactId>
    <version>1.0.0</version>
</dependency>

使用

简单使用
Used with CompletableFuture

import java.util.concurrent.CompletableFuture;

class Test {
    // The main thread executes CompletableFuture tasks, avoiding the use of ForkJoinPool
    public void usingCompletableFuture() {
        CurrentThreadExecutor executor = new CurrentThreadExecutor();
        CompletableFuture<String> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // main thread
            return "Hello " + Thread.currentThread().getName();
        }, executor);
        String hello = executor.start(voidCompletableFuture);
        System.out.println(hello); // Hello main
    }
}

只使用主线程发起、处理并等待100个异步请求结束
Only use the main thread to initiate, process and wait for the end of 100 asynchronous requests

import java.util.concurrent.CompletableFuture;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

class Test {
    public void httpRequest() {
        var currentThreadExecutor = new CurrentThreadExecutor();

        // HttpClient JDK11+
        var client = HttpClient.newBuilder()
                .executor(currentThreadExecutor) //selector executor default is: Executors.newCachedThreadPool(new DefaultThreadFactory(id));
                .build();
        var futures = new ArrayList<CompletableFuture<HttpResponse<String>>>();

        for (int i = 0; i < 100; i++) {
            final int index = i;
            var request = HttpRequest.newBuilder()
                    .uri(URI.create("http://0.0.0.0"))
                    .build();
            var future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                    .whenCompleteAsync((response, exception) -> {
                        // main thread
                        System.out.println("Request: " + index + " completed on " + Thread.currentThread().getName());
                    }, currentThreadExecutor); // default is ForkJoinPool
            futures.add(future);
        }
        var allRequestsFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        currentThreadExecutor.start(allRequestsFuture); // Start processing all tasks until the Future is completed.
        System.out.println("All tasks have been completed");
    }
}

CurrentThreadExecutor is an implementation class based on the Executor interface. The main purpose is to avoid creating threads and use an existing (current) thread to perform all asynchronous tasks. Most JDK APIs use ForkJoinPool by default to perform asynchronous tasks. The implementations provided by Executors are all based on creating threads.In some scenarios where you need to handle a large number of IO tasks but do not want to use multi-threading, CurrentThreadExecutor is a better choice.

It can be used in all classes that are compatible with the Executor interface, such as CompletableFuture and HttpClient. It can also make multiple VirtualThreads execute on one thread.

Scenes to be used

  • Single thread handles a large number of asynchronous IO tasks, eliminating thread pool configuration troubles and multi-thread competition problems.
  • Using asynchronous tools such as CompletableFuture, it is hoped that all tasks will be executed in current thread.
  • Using JDK19+ VirtualThread can also specify this Executor and avoid multi-thread problem.

Features

  • No thread is created, the current thread handles all asynchronous tasks
  • Count the time spent on all tasks. It can be used to evaluate the proportion of CPU calculation time and IO time consumption.
  • interrupt.
  • Timeout terminates execution.
  • Support similar to Node.js next-tick callback
  • JDK8+

About

All tasks are executed in the current thread to avoid creating threads.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages