gpt4 book ai didi

java - Thread.interrupt() 被忽略

转载 作者:行者123 更新时间:2023-12-02 11:26:36 25 4
gpt4 key购买 nike

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

我之前开发过多线程环境,我想我知道 Thread.isInterrupted()Thread.interrupted()InterruptedException 的陷阱code> - 这就是我专门使用 Thread.isInterrupted() 的原因。 编辑:另外,我认为我在这里使用的任何东西都不会抛出InterruptedException

所以我写了这个类:

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 是管理 Mixer 使用和初始化 Thread 以及调用 Thread 对象上的中断的外部类(编辑:该类还接收计算的体积值)。

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

最佳答案

在本例中,我不使用中断 API,而是使用 boolean 标志 isRunning,并在以下情况下将其设置为 false:线程应该停止。

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

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

由于 TargetDataLine.read 表示它可能会阻塞,因此没有理由期望 isInterrupted() 在这里起作用。

如果 TargetDataLine 在收到 InterruptedException 时能够再次中断自身并为我们设置标志,那就太好了,但没有任何规定它必须这样做。

关于java - Thread.interrupt() 被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49577664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com