У меня есть служба веб-сервера, где клиенты запрашивают вычисление смарт-карты и получают результат. Доступный номер смарт-карты может уменьшаться или увеличиваться во время работы сервера, например, я могу физически добавить или удалить смарт-карту из устройства чтения (или многие другие события ... например, исключение и т. Д.).
Вычисление смарт-карты может занять некоторое время, поэтому мне нужно оптимизировать эти задания, чтобы использовать все доступные смарт-карты, если есть одновременные запросы к веб-серверу.
Думал работать с пулом смарт-карт-потоков. Необычным, по крайней мере для меня, является то, что размер пула должен меняться не в зависимости от клиентских запросов, а только от доступности смарт-карты.
Я изучил множество примеров:
- 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 - не мое решение.
Как подойти к этой проблеме? Какому шаблону параллелизма мне следует следовать? правильно ли назначать один поток для каждой смарт-карты или я могу просто использовать семафоры?