是否可以在Java中暂停休眠线程

时间:2014-03-22 19:08:30

标签: java android sleep wait notify

编辑,找到一个解决方法,代码发布在底部。

是否可以暂停使用thread.sleep(sleeptime)的线程?然后当它恢复时,睡觉剩余的时间?

我尝试在这里实现wait / notify设置来暂停一个线程 How to pause/resume thread in Android?

然而,看起来它等到thread.sleep完成了它的休眠时间。

我问这个的原因是因为我在一个线程中使用while循环来播放播放列表中的音乐,我需要线程在音乐曲目的持续时间内休眠,以便音乐曲目在完成之前完成while循环播放播放列表中的下一首歌曲。

例如,while循环将播放持续时间为50秒的歌曲,因此thread.sleep方法将暂停包含while循环的线程。但是,用户希望暂停歌曲,并将整个播放列表放入歌曲25秒。因此,用户将按下暂停按钮25秒进入thread.sleep的50秒睡眠。在用户取消暂停之后,我希望thread.sleep继续剩余的50秒等待(此时还剩25秒)以完成播放歌曲的其余部分。然后while循环将播放播放列表中的下一首曲目。

Runnable whilePlay2 = new Runnable() {
                    @Override
                    public void run(){
                while (k <= myIntArray2.size()-1 ) {
                    System.gc();
                    if( myIntArray2.get(k)>count){
                        video_column_index = videocursor
                                .getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
                        videocursor.moveToPosition(myIntArray2.get(k)-count);
                        filename2 = videocursor.getString(video_column_index);
                    }
                    else{
                    music_column_index = musiccursor
                            .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
                    musiccursor.moveToPosition(myIntArray2.get(k));
                    filename2 = musiccursor.getString(music_column_index);
                    }

                                                try {
                                if (m2MediaPlayer.isPlaying()) {
                                    m2MediaPlayer.reset();
                                }
                                m2MediaPlayer.setDataSource(filename2); 
                                m2MediaPlayer.prepare();
                                m2MediaPlayer.start();      
                                Thread.sleep(m2MediaPlayer.getDuration());
                                synchronized(Lock){
                                    while(onS){
                                        Log.i("should be", "waiting");
                                        Lock.wait();
                                    }
                                    }
                                Log.i("what is on", "on is"+onS);
                                Log.i("k Check", "k is" +k);
                            } catch (Exception e) {
                            }
                    m2MediaPlayer.stop();
                    m2MediaPlayer.reset();
                    k++;
                }
            } //closes public void run(){
                        // TODO Auto-generated method stub
                    };

                Thread whilePlay2T = new Thread(whilePlay2);
                whilePlay2T.start();

这是我的暂停按钮

public void onToggleClicked(View view) {
    // Is the toggle on?
    boolean on = ((ToggleButton) view).isChecked();

    if (on) {
        mMediaPlayer.pause();
        length=mMediaPlayer.getCurrentPosition();
        m2MediaPlayer.pause();
        length2=m2MediaPlayer.getCurrentPosition();
        synchronized (Lock){
            onS=true;
        }
    } else {
        mMediaPlayer.seekTo(length);
        mMediaPlayer.start();
        m2MediaPlayer.seekTo(length2);
        m2MediaPlayer.start();
        synchronized (Lock){
            onS=false;
            Lock.notifyAll();
        }
    }



}

修改

看起来我无法使用它。所以现在我使用递归函数而不是while循环来设置我的播放列表。这是他们中的一个。

public void hiplaylist2(int t2) {
    k=t2;
    if(k <= myIntArray2.size()-1 ){
    System.gc();
    if( myIntArray2.get(k)>count){
        video_column_index = videocursor
                .getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
        videocursor.moveToPosition(myIntArray2.get(k)-count);
        filename2 = videocursor.getString(video_column_index);
    }
    else{
    music_column_index = musiccursor
            .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
    musiccursor.moveToPosition(myIntArray2.get(k));
    filename2 = musiccursor.getString(music_column_index);
    }

                                try {
                if (m2MediaPlayer.isPlaying()) {
                    m2MediaPlayer.reset();
                }
                m2MediaPlayer.setDataSource(filename2); 
                m2MediaPlayer.prepare();
                m2MediaPlayer.start();
                //Thread.sleep(mMediaPlayer.getDuration());
                //SystemClock.sleep(mMediaPlayer.getDuration());
                Log.i("k Check", "k is" + k);
            } catch (Exception e) {
            }
    }
    m2MediaPlayer.setOnCompletionListener(new OnCompletionListener()
    {
        public void onCompletion(MediaPlayer m2MediaPlayer){                            

    m2MediaPlayer.stop();
    m2MediaPlayer.reset();
    if(k < myIntArray2.size()-1 ){
    k++;
    hiplaylist2(k);
    }
    }
    });
};

然后我使用一个线程来同时运行多个这样的线程。

2 个答案:

答案 0 :(得分:2)

我真的不明白。我不确定你想做什么,但我想你的算法至少有两个问题。

首先,当你处理并发任务时要注意你的竞争条件,你的m2MediaPlayer似乎就是其中之一。 关于你的Thread.sleep(m2MediaPlayer.getDuration());我相信你不应该这样做,如果你想等到你的歌曲结束,你只需要:

  1. 从第1主题
  2. 发布您的歌曲
  3. 暂停您的主题1(等待)
  4. 这首歌正在线程2中播放
  5. 当歌曲结束时,从线程2唤醒(通知)你的线程1(让T2死掉)
  6. 请注意,您必须尽可能简化代码,因为并发性很糟糕。

答案 1 :(得分:0)

  

是否可以暂停使用thread.sleep(sleeptime)的线程?然后当它恢复时,睡觉剩下的时间?

假设您询问Java运行时库的行为,那么答案是否为。

  • 暂停和恢复线程没有安全方式。执行此操作的线程suspend / resume方法不安全,在Java 1.1中已弃用。 (如果您需要解释,请阅读this。)

  • 即使您使用不安全的方法,它们也不会神奇地暂停睡眠定时器。事实上,目前尚不清楚睡眠线程会发生什么:未指定

    事实上,如果你发现一个睡眠时间已经过期而且暂停的睡眠线程永远不会醒来,我不会感到惊讶...


我会留给别人处理你的其余问题。

(我无法从你的描述中弄清楚你在这里尝试做什么......以及为什么你甚至需要来暂停一个熟睡的线程。它,听起来你应该使用等待/通知或更高级别的同步类...而不是睡觉。你显然尝试和失败的事实并没有使错误的解决方案。)