gpt4 book ai didi

外部共享资源(智能卡)的 Java 并发模式

转载 作者:太空狗 更新时间:2023-10-29 22:34:39 27 4
gpt4 key购买 nike

我有一个网络服务器服务,客户端请求智能卡计算并获得结果。在服务器正常运行期间,可用的智能卡数量可能会减少或增加,例如,我可以从读卡器中物理添加或移除智能卡(或许多其他事件......如异常等)。

enter image description here

智能卡计算可能需要一段时间,因此如果对 Web 服务器有并发请求,我必须优化这些作业以使用所有可用的智能卡。

我想使用智能卡线程池。不寻常的事情,至少对我来说,是池应该改变它的大小,而不是取决于客户端请求,而只取决于智能卡的可用性。

enter image description here

我研究了很多例子:

  • BlockingQueue:存储请求和停止等待某事的线程看起来不错。
  • FutureTask:我可以使用这个类让客户端等待它的回答,但是应该由哪种执行者来完成任务?
  • ThreadPoolExecutor:似乎是我需要的,但我无法更改池大小,而且每个线程都应链接到一个智能卡插槽。如果我可以更改池大小(在插入智能卡时添加一个线程并在移除智能卡时删除一个线程)并且如果我可以为每个线程分配一个特定的智能卡,这可能是一个解决方案。

这是智能卡控件,每个智能卡我有一个 SmartcardWrapper,每个智能卡都有自己的插槽号。

public class SmartcardWrapper{

private int slot;

public SmartcardWrapper(int slot) {
this.slot=slot;
}

public byte[] compute(byte[] input) {
byte[] out=new byte[];
SmartcardApi.computerInput(slot,input,out); //Native method
return out;
}
}

我尝试为每个智能卡创建一个线程池:

private class SmartcardThread extends Thread{

protected SmartcardWrapper sw;

public SmartcardThread(SmartcardWrapper sw){
this.sw=sw;
}

@Override
public void run() {
while(true){
byte[] input=queue.take();
byte output=sw.compute(input);
// I have to return back the output to the client
}
}
}

每个人都在同一个输入队列中等待:

BlockingQueue<byte[]> queue=new BlockingQueue<byte[]>();

但是如何将智能卡线程的输出返回给网络服务器客户端呢?这让我觉得 BlockingQueue 不是我的解决方案。

如何解决这个问题?我应该遵循哪种并发模式?为每个智能卡分配一个线程是否正确,还是我应该简单地使用信号量?

最佳答案

你的假设:

ThreadPoolExecutor: Seems what I need, but with this I cannot change the pool size, moreover every thread should be linked to a single smartcard slot.

是不对的。

您可以动态设置线程池大小。

看看下面ThreadPoolExecutor API

public void setMaximumPoolSize(int maximumPoolSize)

Sets the maximum allowed number of threads. This overrides any value set in the constructor. If the new value is smaller than the current value, excess existing threads will be terminated when they next become idle.

public void setCorePoolSize(int corePoolSize)

Sets the core number of threads. This overrides any value set in the constructor. If the new value is smaller than the current value, excess existing threads will be terminated when they next become idle. If larger, new threads will, if needed, be started to execute any queued tasks.

Core and maximum pool sizes:

ThreadPoolExecutor 将根据 corePoolSizemaximumPoolSize 设置的范围自动调整池大小。

当在方法execute(java.lang.Runnable) 中提交新任务,并且正在运行的线程少于corePoolSize 时,将创建一个新线程来处理请求,即使其他工作线程空闲。

如果有超过 corePoolSize 但少于 maximumPoolSize 的线程在运行,只有当队列已满时才会创建一个新线程。

通过将 maximumPoolSize 设置为一个基本无界的值,例如 Integer.MAX_VALUE您允许池容纳任意数量的并发任务 .但我不建议拥有那么多线程。请谨慎设置此值。

最典型的是,核心和最大池大小仅在构造时设置,但它们也可以使用 setCorePoolSize(int) 和 setMaximumPoolSize(int) 动态更改。

编辑:

为了更好的利用线程池,如果你知道卡的最大数量是6,你可以使用

 ExecutorService executor = Executors.newFixedThreadPool(6);

关于外部共享资源(智能卡)的 Java 并发模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34138795/

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