没有设置中断标志

时间:2014-02-06 22:19:58

标签: java multithreading swing

我正在使用一个线程来捕获第一次工作的音频输入。但是,我得到一个java.lang.IllegalThreadStateException,我发现是因为没有设置中断标志。我能得到的任何帮助都会很棒:)下面是一个完全可编译的例子。

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class MainFrame extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


    public MainFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setBounds(100, 100, 618, 373);

        Sessioninprogress sip = new Sessioninprogress(this);
        sip.setVisible(true);
        setContentPane(sip);
        setLayout(null);
    }
}




import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.sound.sampled.*;

import java.io.*;
import java.awt.Color;

import javax.swing.JButton;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Font;

import javax.swing.JLabel;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class Sessioninprogress extends JPanel {

     // path of the wav file
     File wavFile = new File("C:/userconvo.wav");

     // format of audio file
     AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;

     // the line from which audio data is captured
     TargetDataLine line;   

     ExecutorService executorService = Executors.newFixedThreadPool(1);  

 public Sessioninprogress(final MainFrame parent) {


 setBounds(100, 100, 618, 373);
 setBackground(new Color(255, 250, 250));
 setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
 setLayout(null);

     JLabel txtpnEmployeeLogin = new JLabel();
     txtpnEmployeeLogin.setForeground(Color.DARK_GRAY);
     txtpnEmployeeLogin.setBackground(Color.WHITE);
     txtpnEmployeeLogin.setFont(new Font("Tahoma", Font.PLAIN, 34));
     txtpnEmployeeLogin.setText("Session in progress");
     txtpnEmployeeLogin.setBounds(150, 123, 409, 52);
     add(txtpnEmployeeLogin);

   final JButton captB = new JButton();
   captB.setFont(new Font("Tahoma", Font.PLAIN, 14));
   captB.setBackground(UIManager.getColor("EditorPane.selectionBackground"));
   captB.setBounds(225, 228, 153, 52);
   captB.setText("Start");   
   captB.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
           if (captB.getText().startsWith("Start")) {
               captB.setText("Stop");              
               executorService.execute(new Runnable() {
                    public void run() {
                        beginCapture();                 }
                });                        
             } else {
               captB.setText("Start");
               finish();
             }             

       }
   });
   add(captB);




 }

 // * Defines an audio format
 AudioFormat getAudioFormat() {
     float sampleRate = 16000;
     int sampleSizeInBits = 8;
     int channels = 2;
     boolean signed = true;
     boolean bigEndian = true;
     AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits,
                                          channels, signed, bigEndian);
     return format;
 }
 // * Captures the sound and record into a WAV file
 void beginCapture() {
     try {
         AudioFormat format = getAudioFormat();
         DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

         // checks if system supports the data line
         if (!AudioSystem.isLineSupported(info)) {
             System.out.println("Line not supported");
             System.exit(0);
         }
         line = (TargetDataLine) AudioSystem.getLine(info);
         line.open(format);
         line.start();  
         AudioInputStream ais = new AudioInputStream(line);

         System.out.println("Start recording...");

         // start recording
         AudioSystem.write(ais, fileType, wavFile);

     } catch (LineUnavailableException ex) {
         ex.printStackTrace();
     } catch (IOException ioe) {
         ioe.printStackTrace();
     }
 }

  //* Closes the target data line to finish capturing and recording
 void finish() {
     line.stop();
     line.close();
     System.out.println("Finished");
 }
}

更新:

这是工作示例。我通过切换到ExecutorService修复了这个问题。

2 个答案:

答案 0 :(得分:2)

问题在于:

if(!t.isAlive())
    t.start();

线程只能启动一次。来自JavaDoc

  

不止一次启动线程永远不合法。特别是,a   一旦完成执行,线程可能无法重新启动。

这就是为什么它第一次有效,但不是后续尝试。

答案 1 :(得分:1)

  

然后,我将如何让它在后续尝试中发挥作用?

以下是一些选项。

  1. 每次创建一个新的Thread
  2. 更改设计,以便run()方法不会终止。相反,当它“完成”一个任务时,让它(比方说)等待一个条件变量,告诉它还有更多的工作要做,等等。
  3. 使用ExecutorService代替裸Thread
  4. (最后一个选项可能是最好的......)