1 Reply Latest reply: Jan 10, 2011 12:36 PM by captfoss RSS

    TargetDataLine.start() event doesn't occur

    829497
      Hello everybody,

      I've got a problem with a LineListener that is not informed about a specific LineEvent.
      I created a class Recorder that implements LineListener and uses a TargetDataLine object on which it registers itself as listener.

      Here's the code snippet, so you know what I mean:

      public class DictateRecorder implements LineListener
      {
          final private TargetDataLine line;
          private boolean bHasListener = false;
      
      
          public DictateRecorder()
                  throws LineUnavailableException
          {
              // initialisation of line is given here
          }
      
      
          public void stop()
          {       
              synchronized(line)
              {
                  line.stop();
              }
          }
      
      
          public void record() throws LineUnavailableException
          {
              if(!bHasListener)
              {
                  synchronized(line)
                  {
                      line.addLineListener(this);
                  }
                  bHasListener = true;
              }
      
              synchronized(line)
              {
                  line.open(); //update() will be entered
                  line.start(); //update() will only be entered, if the thread will sleep some time
              }
      
              new Thread()
              {
                  @Override
                  public void run()
                  {
                      try
                      {
                          final ByteArrayOutputStream byteOutStream =
                                  new ByteArrayOutputStream();
                          
                          sleep(750);  // workaround
      
                          byte[] frame = new byte[2];
                          int iBytesRead = 0;
      
                          do
                          {
                              synchronized(line)
                              {
                                  iBytesRead = line.read(frame, 0, frame.length);
                              }
                              byteOutStream.write(frame, 0, iBytesRead);
                          }while(0 < iBytesRead);
                          synchronized(line)
                          {
                              line.close();
                          }
                      }
                      catch(LineUnavailableException luex){
                      }
                      catch(Exception ex){
                      }
                  }
              }.start();
          }
      
      
          public void update(LineEvent event)
          {
              // not entered when line.start() and sleep() is commented out - event.getType() == LineEvent.Type.START
              // always entered when line.open() - event.getType() == LineEvent.Type.OPEN
          }
      }
      As indicated in the above comments, when invoking line.start(), the LineEvent.Type.START does only occur when the thread is sent to sleep for a while. Assuming the line sleep(750) is not in the code, the update() method will never be entered for LineEvent.Type.START. Not even delayed but never.
      Can somebody please explain me why? Thanks!

      P.S.: I use synchronized statements so the line object can be used by multiple threads without concurrent method access. For example, the stop() method might be called while read access within the thread. I am not perfectly sure if that is needed but it feels somehow safe.

      JRE 6 Update 23 (64 Bit)
      JDK 6 Update 23 (64 Bit)
        • 1. Re: TargetDataLine.start() event doesn't occur
          captfoss
          P.S.: I use synchronized statements so the line object can be used by multiple threads without concurrent method access. For example, the stop() method might be called while read access within the thread. I am not perfectly sure if that is needed but it feels somehow safe.
          This isn't written in the documentation anywhere that I'm aware of, but I'm about 99% sure that lines are threadsafe and there's no need for the syncronization code... so get rid of it.
          Can somebody please explain me why? Thanks!
          First, get rid of whatever syncronization code you've put in... lines should already be threadsafe and syncronizing on them is just not a good idea. I'd worry that your syncronization code is actually causing the problem...

          And then report back with the new code and report the new behavior of your code...