Я провел некоторое исследование с моей проблемой и по-прежнему не могу решить проблему. Threading для меня новичок, и у меня проблемы с пониманием. В моей программе я начинаю поток, который передает файлы в определенный промежуток времени. SWT используется для GUI в этой программе. В моем главном коде пользовательского интерфейса у меня есть кнопка паузы и воспроизведения. Кнопка воспроизведения и связанной с ними код:IllegalMonitorStateException при попытке ждать() поток
playButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if(isRunning){
// TODO implies runningThread is waiting, notify it
}else{
playButton.setEnabled(false);
pauseButton.setEnabled(true);
try {
play();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
public void play() throws IOException{
if(controller.timMan.getEventSendPreferences().equalsIgnoreCase("manual")){
isRunning = true;
manualThread.start();
}else if(controller.timMan.getEventSendPreferences().equalsIgnoreCase("timed")){
isRunning = true;
timerThread.start();
}
return;
}
timerThread реализован как таковой:
timerThread = new Thread(new RunOnTimer(controller));
public static class RunOnTimer implements Runnable{
ScriptController controller;
public RunOnTimer(ScriptController c){
controller = c;
};
@Override
public void run(){
try{
synchronized(this){
controller.runOnTimer();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
и здесь функция runOnTimer() вызывается в перспективе:
public void runOnTimer() throws IOException{
for(File f : dirMan.getEventFileList()){
int randomTimeValue = 0;
int range = timMan.getUpperTimerBound() - timMan.getLowerTimerBound();
if(range > 0)
randomTimeValue = (new Random().nextInt(timMan.getUpperTimerBound() - timMan.getLowerTimerBound()) + 0);
try {
Thread.sleep(1000 * (randomTimeValue + timMan.getLowerTimerBound()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dirMan.updateFileCounts();
System.out.println("Event " + dirMan.getSentEventFiles());
File dest = new File(dirMan.getDestinationFolder() + "\\" + f.getName());
Files.copy(f.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
updateFileCounts();
return;
}
Проблема начинается не тогда, когда поток работает, но когда я вызываю поток, чтобы ждать в реализации приостановленных кнопок прослушивателя.
pauseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if(timerThread.isAlive()){
try {
timerThread.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
pauseButton.setEnabled(false);
playButton.setEnabled(true);
}
});
В других вопросах, которые я прочитал, и от того, что результатов показал Google, синхронизация, как правило, проблема, когда речь заходит об этой ошибке. Что-то связано с получением владельца монитора объектов. Опять же, я не работал с потоками, поэтому эта концепция объектных мониторов для меня загадка. Итак, после прочтения этих вопросов я попытался использовать синхронизацию в методе run() класса RunOnTimer, но, похоже, ничего не изменил при попытке «приостановить» (т. Е. Заставить поток ждать).
Что мне недостает или что-то не так. Программа будет работать нормально, и поток будет работать, как я ожидал, за исключением ошибки, конечно.
Не могли бы вы предоставить трассировку стека ошибки? Кроме того, вам не нужен вызов 'return' в конце методов void. – RamV13