There is a project on Spring-MVC. The project has a JRecorder extends Thread class JRecorder extends Thread , with the start() and stop() methods and the Controller, in which @RequestMapping(value = "/start") and @RequestMapping(value = "/stop") are declared, need to be in /start the start() method of the JRecorder class was JRecorder , and in /stop - the stop() method, respectively. I tried to make a mark. in the following way:

 @Controller public class MainController { ... JRecorder rec = new JRecorder(param1, param2, param3); ... @RequestMapping(value = "/start") .... rec.start(); ... @RequestMapping(value = "/stop") ... rec.stop(); 

With this implementation, after stopping the recording via localhost / stop, the next recording start throws an error: HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalThreadStateException.

Tell me how to properly implement the appeal to methods and in general in which direction to dig?

Full listing of the JRecorder class:

 import javax.sound.sampled.*; import java.io.*; import javax.sound.sampled.AudioFileFormat.Type; public class JRecorder extends Thread { private TargetDataLine m_line; private AudioFileFormat.Type m_targetType; private AudioInputStream m_audioInputStream; private File m_outputFile; public JRecorder(){ } public void setM_line(TargetDataLine m_line) { this.m_line = m_line; this.m_audioInputStream = new AudioInputStream(m_line); } public void setM_targetType(Type m_targetType) { this.m_targetType = m_targetType; } public void setM_outputFile(File m_outputFile) { this.m_outputFile = m_outputFile; } public void start() { m_line.start(); super.start(); } public void stopRecording() { m_line.stop(); m_line.close(); } public void run() { try { AudioSystem.write( m_audioInputStream, m_targetType, m_outputFile); } catch (IOException e) { e.printStackTrace(); } } } 

Full listing of the class MainController:

 @Controller public class MainController { @Autowired private JRecorder jRecorder; //= new JRecorder(); public JRecorder getjRecorder(){ return jRecorder; } public void setjRecorder(JRecorder jRecorder){ this.jRecorder = jRecorder; } @RequestMapping(value = "/", method = RequestMethod.GET) public ModelAndView main() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("index"); return modelAndView; } @RequestMapping(value = "/start") public ModelAndView start() { ModelAndView modelAndView = new ModelAndView(); ReadFromFile rff = new ReadFromFile(); DateAndTime dat = new DateAndTime(); String path = rff.getPath(); String name = rff.getName(); String date = dat.getDate(); String time = dat.getTime(); File outputFile = new File(path+name+"-"+date+"-"+time+".wav"); AudioFormat audioFormat = new AudioFormat( 16000, 8, 1, false, false); DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat); TargetDataLine targetDataLine = null; { try { targetDataLine = (TargetDataLine) AudioSystem.getLine(info); } catch (LineUnavailableException e1) { e1.printStackTrace(); } try { targetDataLine.open(audioFormat); } catch (LineUnavailableException e1) { e1.printStackTrace(); System.exit(1); } } AudioFileFormat.Type targetType = AudioFileFormat.Type.WAVE; modelAndView.setViewName("start"); jRecorder = this.getjRecorder(); jRecorder.setM_line(targetDataLine); jRecorder.setM_targetType(targetType); jRecorder.setM_outputFile(outputFile); jRecorder.start(); System.out.println("Start rec"); return modelAndView; } @RequestMapping(value = "/stop") public ModelAndView stop() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("stop"); jRecorder = this.getjRecorder(); jRecorder.stopRecording(); System.out.println("Stop rec"); return modelAndView; } } 

    2 answers 2

    Do not inherit JRecorder from Thread . Replace inheritance with composition.

    Let JRecorder when calling start() create a new thread (if it has not yet been created), put it in the volatile field and start it.

    In the stopRecording() method, stop the stream and clear the field.

    • Thank you, everything works - Gest

    It is impossible to do Thread.start () after the thread has already worked once, in fact, as IllegalThreadStateException says. You need to create a new instance of JRecorder and start it.

    • Clearly, I have just the problem, I cannot understand how and where to correctly initialize an instance of the class so that it is available in both mappings. - Gest