Background:

我正在创建我想要开源的库. 该库设计用于后端进程. 我将提供的服务利用Java的ProcessBuilder来执行几个本机命令. 此服务通常在1秒内完成命令处理,但在极少数情况下,可能需要几分钟.

Questions:

在公共库具有可能被阻塞的方法的情况下,该库是否应该提供用于调用该方法的异步选项?或者,这样的库应该保持不变,让用户来实现吗?

以下是我一直在考虑如何实现这项服务的几种方式……

Example 1: unopinionated

  • SomeService,采用阻塞方法
  • 如果用户想要异步运行,他们必须弄清楚

SomeService.java

public class SomeService {
    public Response process(Request request) {
        //do stuff for 60 seconds
    }
}

Example 2: opinionated

  • SomeService,采用阻塞方法
  • 可选的SomeProcessTask,用户可以使用它绕过阻塞方法并运行异步.

SomeProcessTask.java

public class SomeProcessTask implements Callable<Response> {
    private final Request request;

    public SomeProcessTask(Request request) {
        this.request = request;
    }

    @Override
    public Response call(Request request) {
        //do stuff for 60 seconds
    }
}

SomeService.java

public class SomeService {
    public Response process(Request request) {
        SomeProcessTask task = new SomeProcessTask(request);
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Response> future = executor.submit(task);
        return future.get();
    }
}

推荐答案

您 comments :

我对并发不是很有经验

那么你绝对应该try 让你的库同时运行.Concurrency is tricky.问题中的代码就是一个例子;注释中发现了多个并发问题.

让你的库保持简单.👉Focus on its core purpose.如果调用程序员认为并发很重要,就让他们处理它.

👉你应该同时接触你的库中可能影响它使用的任何方面.最特别的是,提到任何可能与virtual threads的使用相矛盾的问题.这些问题包括:

  • native code呼喊.
  • 100 blocks内运行长时间执行的工作.(或者重新实施ReentrantLock.)
  • CPU-bound、长期工作.例如,视频编码没有任何阻塞调用,如日志(log)记录,文件I/O,数据库交互或网络访问.

要了解有关并发的更多信息,请阅读Brian Goetz等人的书Java Concurrency in Practice.并研究一下Java Memory Model.

要了解虚拟线程,请参阅罗恩·普雷斯勒、艾伦·贝特曼或何塞·保马德的演讲.

Java相关问答推荐

Jooq隐式地将bigint转换为数字,并且索引不起作用

表格栏上的事件过滤器在PFA中不起作用

RxJava PublishSubject缓冲区元素超时

将成为一个比较者.比较…在现代Java中,编译器会对`CompareTo`方法进行优化吗?

是否保证在事务性块的末尾标记违反约束?

SpringBootreact 式Web应用程序的Spring Cloud Configer服务器中的资源控制器损坏

返回响应时,CamelCase命名约定不起作用

对字符串长度进行排序,但颠倒了顺序(最长字符串在前)

如何使用路径过渡方法使 node 绕圆旋转?

使用Jackson库反序列化json

Spring Boot中的应用程序.properties文件中未使用的属性

如何获得凌空cookies ,并设置它在下一个请求- android

S数学.exp的相同错误保证也适用于StrictMath.exp吗?

具有多个模式的DateTimeForMatter的LocalDate.parse失败

如何在字节数组中反转UTF-8编码?

如何在Struts2中使用操作类中的结果注释重定向到不同的命名空间

字符串的Gzip压缩在java11和java17中给出了不同的结果

Java方法参数:括号中的类型声明?

睡眠在 Spring Boot 中

移动二维数组的行