Я пытаюсь настроить сервер, который предоставляет истинно-случайный номер с устройства, Quantis - Quantum Random Number Generator
. Я создал веб-приложение с платформой Grails, работая на сервере Tomcat
по адресу Ubuntu
.Очередь потоков одиночных ресурсов для потоков Grails/java
Поскольку есть только 1 устройство, я должен запланировать потоки, которые обращаются к нему, правильно? Поэтому я устанавливаю семафоры (с 1 ресурсом) на функции (ReadInt, ReadDouble, ReadFloat
), которые вызывают это устройство. Объект, который содержит эти функции, называется Quantis
, хранящимся в Java Source Packages для приложения Grails, он реализован как одноэлементный; контроллеры затем вызовут и экземпляр этого объекта и его функций. Затем каждая из этих функций вызовет библиотеку Quantis в системе для чтения потока с устройства < - теперь это критическая зона. Мне нужно убедиться, что на это устройство только один запрос.
Семафоры, похоже, работают нормально. Но если я обновляю страницу (получая поток случайных чисел) очень быстро (например, +/- 10 раз), он сбой. Я «слепо» попробовал много подходов из Интернета, включая grails executors
, но ничего не работает (однако, возможно, я не реализовал их правильно, действительно).
Есть ли у кого-нибудь идеи, как я могу это решить?
Вот мой код для одной из функций: (все они выглядят примерно в том же стиле, но вызывая различные функции системной библиотеки при извлечении данных)
private static final Semaphore ticket = new Semaphore(1, true); ... public int ReadInt(int min, int max) throws QuantisException { while (true) { try { ticket.acquire(); int data = QuantisReadScaledInt(deviceType.getType(), deviceNumber, min, max); ticket.release(); return data; } catch (InterruptedException ex) { } catch (QuantisException ex) { ticket.release(); throw ex; } } }
Hi Nizet, Большое спасибо за ввод. Говоря о сбое, я имею в виду, когда есть несколько запросов на подключение к устройству, сервер tomcat будет аварийно завершен, и выходы журнала:
Но когда я реализую семафор, он действительно работает нормально, пока мы не протестируем его с помощью нескольких соединений (освежая) запросы действительно очень быстро. Спасибо, я попробую то, что вы только что сказали .. –ой и почти забыл: нет, api не java api. Это C-библиотека с оболочкой java. и из того, что я вижу, я не думаю, что он синхронизирован. Кроме того, прежде чем я сфотографировал семафор, он сразу же сработает, если я обновляю запрос очень быстро всего три раза. Поскольку исключений нет, и в сообщении об ошибке говорится (в самом конце), что ошибка возникает из-за пределов JVM, я уверен, что она исходит из библиотеки C, потому что несколько запросов запрашивают устройство, когда оно заблокировано используя текущую нить. –
Я не эксперт в собственном коде, но, возможно, в библиотеке tye C, даже если только один поток вызывает его сразу, не может использоваться вообще несколькими потоками. В этом случае вы должны выделить один поток для использования API. Если это так (но это должно быть документировано!), И вы не знаете, как это сделать, задайте другой вопрос, и я буду рад ответить. –