当前位置: 首页 > 面试题库 >

即使我正在调用thread.interrupt(),线程也不会中断

傅涵忍
2023-03-14
问题内容

我正在学习如何在Android中使用线程,并且为此,我制作了一个播放一系列html" target="_blank">笔记的小型应用程序。这个想法是,有一个开始按钮和一个结束按钮,(显然)如果您按下开始按钮,它将开始播放音乐,而如果您按下结束按钮,它将停止播放。开始按钮可以正常工作,但是问题是结束按钮不能正常工作。我在找出原因时遇到了麻烦,因此也许有些人可以帮助我。这是代码:

public class PressAndPlay extends Activity {
    private volatile Thread initBkgdThread;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button startButton = (Button) findViewById(R.id.trigger);
        startButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {

                // create thread
                initBkgdThread = new Thread(new Runnable() {
                    public void run() {
                        play_music();
                    }
                });
                initBkgdThread.start();
            }
        });

        Button endButton = (Button) findViewById(R.id.end);
        endButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                end_music();
            }
        });
    }

    int[] notes = {R.raw.c5, R.raw.b4, R.raw.a4, R.raw.g4};
    int NOTE_DURATION = 400;
    MediaPlayer m_mediaPlayer;

    private void play_music() {
        for(int ii=0; ii<12; ii++) {
            //check to ensure main activity is not paused
            if(!paused) {
                if (m_mediaPlayer != null) {m_mediaPlayer.release();}
                m_mediaPlayer = MediaPlayer.create(this, notes[ii%4]);
                m_mediaPlayer.start();
                try {
                    Thread.sleep(NOTE_DURATION);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void end_music() {
         if(initBkgdThread != null) {
             initBkgdThread.interrupt();
             initBkgdThread = null;
         }
    }

    boolean paused = false;
    @Override
    protected void onPause() {
        paused = true;
        super.onPause();
    }
    @Override
    protected void onResume() {
        super.onResume();
        paused = false;
    }
}

问题答案:

您正在调用interrupt()正在播放的线程,但sleep此时可能正在等待。这样会睡着扔一个InterruptedException。您需要捕获该异常
退出循环以停止播放:

try {
    Thread.sleep(NOTE_DURATION);
} catch (InterruptedException e) {
    // XXX need to stop playing here, maybe return or break?
    return;
}

由于interrupt()也可能在不同的时间出现,因此您需要测试中断状态并退出循环:

if (!paused && !Thread.currentThread().isInterrupted()) {
   ...

同样,需要在两个线程之间共享的所有变量都synchronized被标记或被标记volatile。该paused标志可能应该volatile在这里:

volatile boolean paused = false

最后,为了后代,当您捕获时InterruptedException,它将清除线程的中断状态。通常,最好立即在线程上设置中断标志,以便其他人可以对其进行测试:

try {
    Thread.sleep(NOTE_DURATION);
} catch (InterruptedException e) {
    // re-establish the interrupt condition
    Thread.currentThread.interrupt();
    ...
}


 类似资料:
  • 问题内容: 在某个线程上调用an 时,该线程会发生什么? 问题答案: 目标线程是“中断的”。通常,在该线程中设置一个标志,该线程可以查看该标志(带有)。如果目标线程当前在某些I / O上被阻塞,则分别使用an 或an 唤醒它。 线程中断是微调线程的一种温和方法。它是用来给线程有机会退出 干净 ,而不是,这更像是一支突击步枪射击的线程。

  • 在下面的代码中,线程。activeCount()始终返回2,即使executor中的线程在5秒后终止。 我期望Thread.activeCount()在5秒后返回1。为什么它总是返回2?

  • 问题内容: 一个众所周知的事实是,不要停止使用Thread.stop()运行进程。 通常,手册和教程建议改用Thread.interrupt()或一些布尔变量,并从代码内部检查该中断或变量。 但是,如果我有一个库方法有时需要花费很长时间才能执行,并且我想让用户能够停止该过程?库没有给我提供执行此操作的机制(不检查线程中断状态,也没有“ stop!”变量)? 而且,更糟糕的是,要么没有库的源代码,要

  • 问题内容: 我的一项活动遇到了一个奇怪的问题。从拍照/录像回来时,我正在显示一个对话框,允许用户命名相机。用户按下“确定”后,我将使用所请求的文件名发送给主题,该主题将复制文件(并显示进度对话框)。 由于某种原因,即使我调用,总是在主线程上调用执行复制的函数。 更改呼叫以解决问题。我还是想知道为什么它不起作用… 问题答案: 并且是那里最混乱的运营商。前者确保订阅副作用在指定的调度程序(线程)上发生

  • 问题内容: 有人可以告诉我线程开始执行的顺序吗?我写了下面的代码 还有这个 当我执行此代码时,我得到许多不同的输出。 另一个, 为什么会这样呢?线程顺序永远不会相同吗?如果有人可以给我一些有关线程和示例基础的知识,那就太好了。PS:我是线程的新手,这是我的第一个线程程序。提前致谢。 问题答案: 当我执行此代码时,我得到许多不同的输出。 这是预期的。该顺序未定义,并且随着线程开始运行并由OS进行线程

  • 我正在创建一个如下所示的JobDetail,