从正在运行的Thread调用方法

时间:2014-03-10 22:06:44

标签: java multithreading methods runnable

所以我试图制作一个在单独的线程上运行的音乐播放器。我想让Player类(实现Runnable)内的方法暂停,播放并转到下一首/上一首歌。如果我要调用Thread的内部方法,它是否仍然在一个单独的线程上运行?一切都按预期工作,但我仍然是Threads的新手,所以我不确定这是不是很好的做法。有人可以对此有所了解吗?

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 player = new Player(0);
playerThread = new Thread(player, Player.TAG);
playerThread.start();

并且调用了player.pause(),然后来自另一个线程的player.play(),玩家是否还会在单独的线程上运行?

2 个答案:

答案 0 :(得分:2)

  

如果我要调用Thread的内部方法,它是否仍然在一个单独的线程上运行?

没有。线程不是魔术。当您调用方法时,您正在使用当前线程调用该方法。要分叉一个线程,你实际上必须创建一个线程对象(或执行器服务)并启动它。然后它调用run()等等。

因此,如果您调用player.pause(),您将从当前线程(可能是“主”线程)调用暂停。您的playerThread将在后台执行其他操作。 pause()方法为synchronized的全部原因是,您可以从外部线程 playerThread获取所有内容,而不会重叠它们。这也意味着多个线程可以测试和设置isPlaying布尔值,其他线程将看到更新。

您最有可能从Java thread tutorial开始。

答案 1 :(得分:1)

run()方法的内容是在单独的线程上执行的内容。调用包含run()的类的方法的任何内容都将在其自己的线程上执行该方法。因此,您必须确保任何数据访问都是正确的线程安全的。