Я хотел бы знать, как слушатель должен сообщить родительскому потоку, что он был вызван. (В основном я пытаюсь заставить асинхронный вызов быть синхронным.) Мой пример включает вызовы Android, но это скорее общий вопрос синхронизации ...
Метод myMethod () запрашивает, чтобы SoundPool загрузил звук и уведомил слушателя о завершении вызова. Я хотел бы, чтобы myMethod () дождался вызова слушателя, прежде чем вернуться. Код, который я придумал:
void myMethod() {
SoundPool soundPool = ...;
final Lock object = new Object();
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener(){
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
synchronized(lock) {
lock.notify();
}
}});
synchronized(lock) {
int soundId = MediaUtil.loadSoundPool(soundPool, ...); // returns immediately
lock.wait();
}
}
(я упустил try / catch для простоты, хотя это и есть в реальном коде.) Обычно у меня также есть флаг при обмене данными между двумя потоками, но я не могу использовать локальную переменную для этой цели, так как он должен быть последним, чтобы быть доступным из анонимного класса, а переменная экземпляра выглядит как нарушение абстракции (и должна быть изменчивой).
Безопасен ли вышеуказанный код и / или есть ли лучший способ решить проблему?