首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略Thread.interrupt()

忽略Thread.interrupt()
EN

Stack Overflow用户
提问于 2018-03-30 16:11:11
回答 2查看 283关注 0票数 0

我正在尝试编写一个算法来计算声卡输入的音量。虽然这(或多或少)不是问题,但我在多任务处理时遇到了麻烦。我从另一个线程调用的中断似乎被忽略了。

我以前开发过多线程环境,我想我知道Thread.isInterrupted()Thread.interrupted()以及InterruptedException的缺陷--这就是为什么我只使用Thread.isInterrupted()的原因。编辑:而且我认为我在这里使用的任何东西都会抛出InterruptedException

所以我写了这门课:

代码语言:javascript
复制
import javax.sound.sampled.*;

public class SoundListener extends Thread {

    /**
     * RMS refresh rate in Hz (1000ms / RESPONSE_TIME)
     */
    private static final int REFRESH_RATE = 40;

    private final SoundMeter SOUNDMETER;
    private final AudioFormat AUDIO_FORMAT;
    private final int BUFFER_SIZE;
    private final boolean IS_24_BITS;
    private final TargetDataLine TARGET_DATA_LINE;

    SoundListener(SoundMeter soundMeter, Mixer mixer, AudioFormat audioFormat) throws LineUnavailableException {
        SOUNDMETER = soundMeter;
        AUDIO_FORMAT = audioFormat;
        BUFFER_SIZE = (int) ((AUDIO_FORMAT.getSampleRate() * AUDIO_FORMAT.getSampleSizeInBits()) / REFRESH_RATE);
        IS_24_BITS = AUDIO_FORMAT.getSampleSizeInBits() == 24;
        TARGET_DATA_LINE = AudioSystem.getTargetDataLine(AUDIO_FORMAT, mixer.getMixerInfo());
        TARGET_DATA_LINE.open(AUDIO_FORMAT);
        TARGET_DATA_LINE.start();

        setName("SoundListener");
        setDaemon(true);
        start();
    }

    @Override
    public void run() {

        System.out.println("Thread " + getName() + " started!");

        while (!isInterrupted()) {

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = TARGET_DATA_LINE.read(buffer, 0, BUFFER_SIZE);

            if (bytesRead >= 0) {

                int max = 0;
                for (int i = 0; i < bytesRead; ) {

                    byte[] subBuffer = new byte[3];
                    subBuffer[0] = buffer[i++];
                    subBuffer[1] = buffer[i++];

                    if (IS_24_BITS) {
                        subBuffer[2] = buffer[i++];
                    }

                    int currentValue = 0;
                    if (AUDIO_FORMAT.isBigEndian()) {
                        if (IS_24_BITS) {
                            currentValue += subBuffer[0] << 16;
                            currentValue += subBuffer[1] << 8;
                            currentValue += subBuffer[2];
                        } else {
                            currentValue += subBuffer[0] << 8;
                            currentValue += subBuffer[1];
                        }
                    } else {
                        if (IS_24_BITS) {
                            currentValue += subBuffer[2] << 16;
                        }
                        currentValue += subBuffer[0];
                        currentValue += subBuffer[1] << 8;
                    }

                    if (currentValue > max) {
                        max = currentValue;
                    }
                }
                SOUNDMETER.setVolume(max);
            }
        }
        TARGET_DATA_LINE.close();

        System.out.println("Thread " + getName() + " stopped!");
    }
}

它在初始化时启动输入接口,然后立即启动自己。

SoundMeter是管理混合程序以使用和初始化线程以及调用线程对象上的中断的外部类(Edit:该类还接收计算的卷值)。

我认为问题在于阻塞TargetDataLine.read()方法,但我不知道如何解决这个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-30 16:24:38

在本例中,我只使用boolean标志isRunning,而不是使用中断API,并在线程停止时将其设置为false

我们可能无法观察到interrupt()设置的标志,特别是当线程阻塞时:

如果该线程在调用wait()wait(long)Object类的wait(long, int)方法或调用join()join(long)join(long, int)sleep(long)sleep(long, int)等方法时被阻塞,则将清除该线程的中断状态并接收InterruptedException

因为TargetDataLine.read说它可能会阻塞,所以没有理由期望isInterrupted()在这里工作。

如果TargetDataLine能够在接收到InterruptedException时再次中断为我们设置标志,那就太好了,但是没什么可说的。

票数 0
EN

Stack Overflow用户

发布于 2018-03-30 16:18:11

Thread.interrupt()以普通的方式设置标志,仅此而已

如果前面的条件都不成立,那么这个线程的中断状态就会被设置。

因此,在调用isInterrupted()之后,线程将在第一次检查期间结束(!Thread.interrupt() )

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49577664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档