代码之家  ›  专栏  ›  技术社区  ›  ChrisMcJava

从正在运行的线程调用方法

  •  3
  • ChrisMcJava  · 技术社区  · 10 年前

    所以我正在尝试制作一个在单独线程上运行的音乐播放器。我希望在Player类(实现Runnable)中有方法来暂停、播放和转到next/prev歌曲。若我要调用线程的内部方法,它还会在单独的线程上运行吗?一切都正常工作,但我对线程还是新手,所以我不确定这是否是好的实践。有人能解释一下吗?

    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 回复  |  直到 10 年前
        1
  •  3
  •   Gray droiddeveloper    10 年前

    若我要调用线程的内部方法,它还会在单独的线程上运行吗?

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

    所以如果你打电话 player.pause() 您将从当前线程(可能是“主”线程)调用pause。你的 playerThread 会在后台做其他事情。为什么 pause() 方法是 synchronized 这样你就可以从外线 这个 播放机线程 而不重叠。这也意味着多个线程可以测试和设置 isPlaying 布尔和其他线程将看到更新。

    您最有可能从 Java thread tutorial .

        2
  •  1
  •   aruisdante    10 年前

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