java如何从异步线程返回值
我正在制作一个MediaPlayer
来播放音频文件
当前在主线程上工作
public boolean playFile(String path) {
MediaPlayer mp = new MediaPlayer();
mp.setAudioAttributes(AudioFocusManager.getPlaybackAttributes());
try {
mp.setDataSource(path);
mp.prepare();
mp.start();
mp.setOnErrorListener((mp1, what, extra) -> {
return true;
});
mp.setOnCompletionListener( mp1 -> {
});
return true;
} catch (Exception e) {
return false;
}
}
但我想把它交给遗嘱执行人
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
});
一旦我将其移动到执行器,那么第二个和第三个返回将触发一个错误
Unexpected return value
和playFile
触发以下事件
Missing return statement
我试过使用AtomicReference
AtomicReference<Boolean> correctlyPlayed = new AtomicReference<>(false);
//set up MediaPlayer
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
MediaPlayer mp = new MediaPlayer();
mp.setAudioAttributes(AudioFocusManager.getPlaybackAttributes());
try {
mp.setDataSource(path);
mp.prepare();
mp.start();
mp.setOnErrorListener((mp1, what, extra) -> {
return true;
});
mp.setOnCompletionListener( mp1 -> {
});
correctlyPlayed.set(true);
} catch (Exception e) {
AudioFocusManager.releaseAudioFocus();
correctlyPlayed.set(false);
}
});
return correctlyPlayed.get();
但它总是触发false,这意味着它不会等待线程更新它
我怎么做呢
# 1 楼答案
execute方法需要Runnable,而Runnable不返回任何内容,这就是为什么会出现意外的返回值错误。 您不能像这样直接从单独的线程获取播放文件的返回值,但您使用AtomicReference的方法应该是可行的。 有一个布尔值的内置原子类型,AtomicBoolean,考虑使用它。p>
尝试更改此选项:
为此:
此外,您可能需要同步代码以等待另一个线程在返回之前执行,为此,考虑检查一些信号量同步技术(例如,CurnDutLaCH),我建议您也阅读有关等待通知机制。正如您正确指出的,总是将false作为返回值的原因很可能是同步问题
# 2 楼答案
正如评论所说,使用
executor#submit
而不是executor#execute
,这样您可以得到一个Future
,您可以调用Future#get
来获得结果: