title: Android Semaphores to stop a thread
body: <p>I'm trying to use semaphores to make a thread waiting for something happening outside it with a semaphore, but I don't know why it is not working. Probably is something I don't know about Android semaphores, because I already used the same "way to operate" with some real time operating system (such as FreeRTOS and MXLite) and it works fine.</p>
  
  <p>Practically I have a thread that is running a service each time it executes a while loop inside its run() method. The service execute some long operation and then die, I just want the thread not to run a new service before the previous one has finisched.</p>
  
  <p>The code looks like that (condLog is just a function that doeas a Log.i with the string passed if a DEBUG define is true):</p>
  
  <pre><code> public Handler handler = new Handler() {
       @Override
       public void handleMessage(Message msg) {
           super.handleMessage(msg);
           startScheduler(msg);
       }
   };
  
   private static boolean serviceRunning = false;
   private static Context context; // context is set in the main class contructor
   private executeScheduledAction myThread = new executeScheduledAction();
  
   private void startScheduler(Message msg) {
      condLog("startScheduler- message received...");
      myThread .releaseSemaphore();
   }
  
   private final class executeScheduledAction extends Thread {
      private final static int MAX_CONCURRENT = 1;
      private Semaphore semaphore = new Semaphore(MAX_CONCURRENT, true);
      public executeScheduledAction () {}
      public void releaseSemaphore() {
          semaphore.release();
          condLog("releaseSemaphore - Semaphore released, semaphore permit: " + semaphore.availablePermits());
      }
      @Override
      public void run() {
          condLog( "executeScheduledAction - thread started...");
          serviceRunning = true;
          while(serviceRunning ){
              try {
                  condLog( "executeScheduledAction - taking semaphore, semaphore permits: " + semaphore.availablePermits() );
                  semaphore.acquire(); 
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              condLog("executeScheduledAction - semaphore taken, running service");
              // HERE RUN THE SERVICE
          }
          condLog( "Thread finished...");
      }
  }
  </code></pre>
  
  <p>THe first call myThread.start method. As I expected, the semaphore is taken the first time and the service is correctly launched. At the end, service send a message to an handler that call executeScheduledAction.release...and this is what I obtain in the Logcat:</p>
  
  <p>executeScheduledAction - thread started...</p>
  
  <p>executeScheduledAction - taking semaphore, semaphore permits: 1</p>
  
  <p>executeScheduledAction - semaphore taken, running service</p>
  
  <p>executeScheduledAction - taking semaphore, semaphore permits: 0</p>
  
  <p>startScheduler - message received...</p>
  
  <p>releaseSemaphore - Semaphore released, semaphore permit: 2</p>
  
  <p>Why is it 2 and not 1? it looks like I'm not release the same semaphore I'm acquiring...</p>
  
  <p>Really, any help would be helpfull and appreciated.</p>
  
  <p>Thank you all very much
  Cristiano</p>