Я запускал 3 приложения Java, каждый в своей собственной JVM.Как программы Java в разных JVM-системах могут непреднамеренно влиять друг на друга?
Затем все приложения застыли (в то же время) примерно через 30 минут. При работе только с одной JVM проблема не возникает, и она оказалась стабильной более 13 часов при большой нагрузке. Проблема возникает только при запуске нескольких JVM.
Чтобы уточнить, между программами не существует (предполагаемого) взаимодействия. Кроме того, программы используют 2 потока, каждый из которых работает вместе синхронно. Приложения идентичны, просто работают на разных данных. Опять же, они должны быть полностью независимы друг от друга, поскольку каждая программа работает на собственной JVM.
Я не прошу конкретного решения моей проблемы, но мне интересно узнать, является ли обычное поведение обычным или нет.
И самое главное, если это хорошо известная проблема, существуют ли какие-либо правила большого пальца о том, как избежать таких проблем? Существуют ли аспекты многопоточности (в моем случае каждая программа использует два потока), которые, как известно, вызывают подобные проблемы?
+ Обновление: Прежде всего, вот код, который используется для операций ожидания/уведомления между потоками.
Основная нить, только два метода (называемые в цикле):
public void waitCycles(int c) {
worker.setWaitDuration(c);
try {
synchronized (this) {
this.wait(500);//very unlikely to actually wait 500ms. Should be notified.
}
}
catch (Exception e) {
}
}
float[] learn(boolean[] values) {
worker.setLearnValues(values);
try {
synchronized (this) {
this.wait(500);//Same as above
}
}
catch (Exception e) {
}
float[] out = worker.quality;
worker.quality = null;
return out;
}
А вот код из Рабоче-Class (расширяет тему), а также часть цикла:
if (learnValues != null) {
float[] q = new float[learnValues.length];
for (int i = 0; i < learnValues.length; i++) {
q[i] = outs[i].learn(learnValues[i], 1);
}
quality = q;
learnValues = null;
synchronized (host) {
host.notifyAll();
}
}
//"waiter" is an integer value that is set by calling "setWaitDuration(int c)"
if (waiter > 0) {
waiter--;
if (waiter <= 0) {
waiter = -1;
synchronized (host) {
host.notifyAll();
}
}
}
После замораживания обеих потоков все еще потребляется много процессорного времени, что не имеет смысла, поскольку программы должны писать текстовые файлы, содержащие информацию о текущем ходе обучения, но этого не происходит (несмотря на то, что оба потока все еще работают). Я дважды проверял, нет бесконечных циклов while, которые могут вызвать это. И все еще не имеет смысла, почему все три программы замерзают, казалось бы, в одно и то же время. Я использую JDK8u25 и его встроенную JRE в Windows 8. У меня не было проблем с памятью.
Как они синхронизируются и что делают программы? –
Это программа машинного обучения, точнее искусственная нейронная сеть. Один поток оценивает качество ANN и отправляет ему учебные шаблоны, он также предоставляет несколько инструментов для анализа ANN. Второй поток содержит фактический ANN и выполняет все ANN-конкретные вычисления. Обеим потокам требуется как можно больше процессорного времени. Синхронизация выполняется в случае, если какой-либо поток выполняет действие, которое требует, чтобы другой поток ожидал. В конце спящий поток снова проснулся. Я использую в основном Thread.wait (время) и someMonitor.notifyAll() – Tonnz
Каково состояние системы, когда три JVM зависают? Они вообще используют процессор? Или они все заблокированы? Есть ли другие потоки в JVM, способные добиться прогресса? Кроме того, какие версии ОС и Java? Это не известная проблема, поэтому в вашей системе может быть что-то не так. –