Java 从正在运行的线程调用方法
所以我正在尝试制作一个音乐播放器,它运行在一个单独的线程上。我希望在Player类(实现Runnable)中有暂停、播放和转到next/prev歌曲的方法。若我调用线程的内部方法,它还会在单独的线程上运行吗?一切都正常工作,但我对线程还是新手,所以我不确定这是否是一个好的实践。有人能解释一下吗Java 从正在运行的线程调用方法,java,multithreading,methods,runnable,Java,Multithreading,Methods,Runnable,所以我正在尝试制作一个音乐播放器,它运行在一个单独的线程上。我希望在Player类(实现Runnable)中有暂停、播放和转到next/prev歌曲的方法。若我调用线程的内部方法,它还会在单独的线程上运行吗?一切都正常工作,但我对线程还是新手,所以我不确定这是否是一个好的实践。有人能解释一下吗 class Player implements Runnable, OnCompletionListener { public static final String TAG = "Player"
class Player implements Runnable, OnCompletionListener {
public static final String TAG = "Player";
private MediaPlayer mp;
private boolean isPlaying = false;
private SongsManager sm = null;
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
private int currentSongIndex = 0;
public Player(int currentSongIndex){
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
sm = new SongsManager();
songsList = sm.getSongList();
this.currentSongIndex = currentSongIndex;
}
@Override
public void run() {
try{
mp.reset();
mp.setDataSource(songsList.get(currentSongIndex).get(SongsManager.KEY_PATH));
mp.prepare();
mp.start();
isPlaying = true;
} catch (IllegalArgumentException e){
e.printStackTrace();
} catch (IllegalStateException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
public synchronized void pause() {
if (isPlaying){
if (mp != null){
mp.pause();
isPlaying = false;
}
}
}
public synchronized void play() {
if (!isPlaying){
if (mp != null){
mp.start();
isPlaying = true;
}
}
}
...
}
然后从另一个线程调用player.pause(),然后调用player.play(),那么该播放器是否仍在另一个线程上运行
若我调用线程的内部方法,它还会在单独的线程上运行吗
不,线不是魔法。当您调用一个方法时,您正在使用当前线程调用该方法。要分叉线程,实际上必须创建一个线程对象(或执行器服务)并启动它。然后它调用run()
,等等
因此,如果您调用了player.pause()
,您将从当前线程(可能是“主”线程)调用pause。您的playerThread
将在后台执行其他操作。pause()
方法之所以是synchronized
,是因为您可以从外部线程和playerThread
执行所有操作,而不必重叠。这还意味着多个线程可以测试和设置isPlaying
布尔值,其他线程将看到更新
您最有可能从。开始
run()
方法的内容是在单独的线程上执行的。任何调用包含run()
的类的方法的操作都将在其自己的线程上执行该方法。因此,您必须确保任何数据访问都是线程安全的。好的,谢谢;因此,如果在同步方法中不使用mp.pause()/.start(),我只调用了Player.pause()和Player.start()方法,然后创建了一个新线程(Player,TAG.start()),这将实现我的目标?看起来你对@ChrisMcJava感到困惑。如果您正在调用Player.start()
,则start()
需要是static
。当您在静态
方法上同步时,您正在Player.class
对象上同步,这可能不是您想要的。对不起,我的错误,我不是指Player.start();请允许我重新表述一下:那么,在播放器被实例化之后,创建了一个新的播放器线程(线程playerThread=new thread(player,TAG).start();),然后从主ui线程调用player.pause(),如果我省略了player.play()方法,创建了一个新线程(线程playerThread=new thread(player,TAG).start())当从UI中按下播放按钮时?我想这会管用的
Player player = new Player(0);
playerThread = new Thread(player, Player.TAG);
playerThread.start();