我有一个Web服务器服务,客户端请求智能卡计算并获取结果。
可用的智能卡号可以在服务器正常运行期间减少或增加,例如,我可以从读取器中实际添加或删除智能卡(或其他许多事件,例如异常等)。
智能卡计算可能需要一段时间,因此,如果有对Web服务器的并发请求,我必须优化这些作业以使用所有可用的智能卡。
我认为可以使用智能卡线程池。至少对我而言,不寻常的事情是,池应该更改其大小,而不是取决于客户端请求,而仅取决于智能卡的可用性。
我研究了许多例子:
这是智能卡控件,每个智能卡有一个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[]>();
但是如何将输出从智能卡线程返回到Web服务器客户端?这让我认为BlockingQueue不是我的解决方案。
如何解决这个问题?我应该遵循哪种并发模式?
为每个智能卡分配一个线程是否正确,还是我应该只使用信号量?
最佳答案
您的假设:
是不正确的。
You can set thread pool size dynamically.
看看下面的ThreadPoolExecutor API
public void setMaximumPoolSize(int maximumPoolSize)
public void setCorePoolSize(int corePoolSize)
Core and maximum pool sizes:
ThreadPoolExecutor
将根据corePoolSize
和maximumPoolSize
设置的范围自动调整池的大小。当通过
execute(java.lang.Runnable)
方法提交新任务时,正在运行的线程数少于corePoolSize
时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理请求。如果正在运行的
corePoolSize
线程多但少于maximumPoolSize
线程,则仅当队列已满时才创建新线程。通过将
maximumPoolSize
设置为本质上不受限制的值(例如Integer.MAX_VALUE
),可以允许池容纳任意数量的并发任务。但是我不建议拥有那么多线程。请谨慎设置该值。最典型地,核心和最大池大小仅在构造时设置,但也可以使用
setCorePoolSize(int
和setMaximumPoolSize(int)
动态更改。编辑:
为了更好地利用线程池,如果您知道最大卡数为6,则可以使用
ExecutorService executor = Executors.newFixedThreadPool(6);
或者
关于java - 外部共享资源(智能卡)的Java并发模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34138795/