外部共享资源(智能卡)的 Java 并发模式
我有一个Web服务器服务,客户端请求智能卡计算并获得结果。在服务器正常运行时间期间,可用的智能卡数量可能会减少或增加,例如,我可以在读卡器中物理添加或删除智能卡(或许多其他事件...如例外等)。
智能卡计算可能需要一段时间,因此,如果存在对 Web 服务器的并发请求,我必须优化这些作业以使用所有可用的智能卡。
我想使用智能卡线程池。至少对我来说,不寻常的事情是,池应该改变其大小,而不是取决于客户端请求,而只取决于智能卡的可用性。
我研究了很多例子:
- BlockingQueue:存储请求并停止线程等待某些事情似乎很好。
- FutureTask:我可以使用这个类让客户端等待它的答案,但是哪种类型的执行器应该执行该任务呢?
- ThreadPoolExecutor:似乎是我需要的,但是有了这个,我无法更改池大小,而且每个线程都应该链接到一个智能卡插槽。如果我可以更改池大小(在插入智能卡时添加线程,在删除智能卡时删除线程),并且如果我可以为每个线程分配特定的智能卡,则可以解决此问题。
这是智能卡控件,每个智能卡都有一个智能卡包装器,每个智能卡都有自己的插槽号。
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[]>();
但是如何将输出从智能卡线程返回到Web服务器客户端?这让我认为BlockningQueue不是我的解决方案。
如何解决这个问题?我应该遵循哪种并发模式?为每个智能卡分配一个线程是否正确,或者我应该简单地使用信号量?