gpt4 book ai didi

java - 有没有一种方法可以根据属性将 Runnable Tasks 分组到同一个线程中,以便具有相同属性的 Runnables 同步运行?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:23:30 28 4
gpt4 key购买 nike

假设我有一个 ExecutorService,我用它来运行 Job 对象,这是一个扩展 Runnable 的类。我希望我的 Job 对象并行运行,除了让 2 个 Job 对象具有相同的 job.getTypeId() 是有害的同时运行。因此,如果我要提交 一份工作,我必须首先确保没有相同的job.getTypeId() 正在运行,如果有是,它需要在它后面排队直到它完成。

这是一个边缘案例:具有相同 TypeId 的作业通常不会同时提交,但如果提交,我需要能够正确处理。虽然这是一个边缘案例,但它是一个重要的用例。

我想到的最好的想法是拥有某种 CollectionExecutorServices,其配置类似于 Executors.newSingleThreadedExecutor,就像一个 HashMap,其中我的 TypeId 将是与单线程执行器关联的键。保持这一点,虽然完全有可能,但感觉它比替代解决方案要麻烦得多。问题是,有可能获得多个需要同步运行的 jobs,但之后再也看不到那个 TypeId。我需要实现一种方法来清除一段时间内未使用的任何单线程执行器,以避免从我不断增长的单线程执行器列表中发生内存泄漏。

我只是想知道我是否在尝试解决一个已经解决的问题。

是否已经有一个执行模型可以解决我的问题?有没有办法配置线程池,例如,在线程名称中使用我的 Job.getTypeId() 创建线程,并在提交后分配所有 Job 对象使用相同的 TypeId 到同一个线程?

最佳答案

我的一位同事向我指出了一个很好的解决方案,有人可以随意提供他们认为更好的其他解决方案。解决方案是利用 Guava 的 Striped Locks 来允许线程锁定特定的 JobTypeId。这意味着可以为同一个 JobTypeId 创建两个线程,但第一个创建的线程将锁定该 ID,另一个将被阻止运行,直到锁再次可用。具有相同 TypeId 的作业不在同一个线程上运行,但它们都在同一个stripe

上运行

条纹文档:https://google.github.io/guava/releases/19.0/api/docs/com/google/common/util/concurrent/Striped.html

锁定文档:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html?is-external=true

代码:

public class JobRunner implements Runner {

private final Striped<Lock> locks;
private final int typeId;

public JobRunner(Striped<Lock> locks, int typeId){
this.locks = locks;
this.typeId = typeId;
}

public void run() {
lock = locks.get(typeId);
lock.lock() //This blocks the thread untill the lock becomes available if it wasn't already
doWork()
}

private void doWork(){
//Bus, do your stuff!
}

}

只要所有 JobRunner 共享相同的 Striped<Lock>单例,一切都应该很好。

关于java - 有没有一种方法可以根据属性将 Runnable Tasks 分组到同一个线程中,以便具有相同属性的 Runnables 同步运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49061221/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com