title: From Java to Kotlin: synchronization and lock / wait / notify pattern
body: <h2>Original Context</h2>
  
  <p>Back when developing Android / Java apps, I created a simple class that would allow to me to synchronize taks instead of using the queue logic and / or the callbacks pattern. </p>
  
  <p>Indeed that would allow me to have a series of tasks being performed in a linear way (when looking at the code). In some cases, that's more useful and way more maintainable and debuggable.</p>
  
  <p>The reason behind this need, is that when I am required to work with APIs that provided asynchronous logic with callbacks to be notified of result or failure, such as the Android Bluetooth LE API or Glide (to name a few), I want to be able to synchronize <strong>my code</strong> when using asynchronous APIs.</p>
  
  <p>This is what I came up with:</p>
  
  <h2>Lock.java</h2>
  
  <pre><code>import android.support.annotation.Nullable;
  import android.util.Log;
  
  
  /**
   * This class is a small helper to provide feedback on lock wait and notify process
   */
  public final class Lock&lt;T&gt; {
      private final static String TAG = Lock.class.getSimpleName();
  
      private T result = null;
      private boolean isWaiting = false;
      private boolean wasNotified = false;
  
  
      /**
       * Releases the lock on this instance to notify the thread that was waiting and to provide the result
       * @param result    the result of the asynchronous operation that was waited
       */
      public synchronized final void setResultAndNotify(@Nullable final T result) {
          this.result = result;
          if (this.isWaiting) {
              synchronized (this) {
                  this.notify();
              }
          } else
              this.wasNotified = true;
      }
  
  
      /**
       * This method locks on the current instance and wait for the duration specified in milliseconds
       * @param timeout the duration, in milliseconds, the thread will wait if it does not get notify
       */
      @Nullable
      public synchronized final T waitAndGetResult(final long timeout) {
          if (this.wasNotified) { // it might happen that the notify was performed even before the wait started!
              this.wasNotified = false;
              return this.result;
          }
  
          try {
              synchronized (this) {
                  this.isWaiting = true;
                  if (timeout &lt; 0) {
                      this.wait();
                  } else {
                      this.wait(timeout);
                  }
                  this.isWaiting = false;
                  return this.result;
              }
          } catch (final InterruptedException e) {
              Log.e(TAG, "Failed to wait, Thread got interrupted -&gt; " + e.getMessage());
              Log.getStackTraceString(e);
          }
          return null;
      }
  
  
      /**
       * This method locks on the current instance and wait as long necessary (no timeout)
       */
      @Nullable
      public synchronized final T waitAndGetResult() {
          return waitAndGetResult(-1)
      }
  
  
      /**
       * Tells whether this instance is currently waiting or not
       * @return &lt;code&gt;true&lt;/code&gt; if waiting, &lt;code&gt;false&lt;/code&gt; otherwise
       */
      public final boolean isWaiting() {
          return this.isWaiting;
      }
  }
  </code></pre>
  
  <p>Not the best solution, I'm sure, but, in a way, it does take care of some race conditions in my rare cases where <code>notify</code> could be called before <code>wait</code> is. I believe I could use an <code>AtomicBoolean</code> but so far no problem.</p>
  
  <p>Here is how it can be used:</p>
  
  <pre><code>public final boolean performLongRunningTasks() {
      this.asynchronousTaskA.startAsync();
      final Result taskAResult = this.taskALock.waitAndGetResult(); // wait forever
  
      this.asynchronousTaskB.startAsync();
      final Result taskBResult = this.taskBLock.waitAndGetResult(5000L); // wait up to 5 seconds
  
      return taskAResult != null &amp;&amp; taskBResult != null;
  }
  
  
  // callback
  private void onTaskACompleted(@Nullable Result result) {
      this.taskALock.setResultAndNotify(result);
  }
  
  
  // callback
  private void onTaskBCompleted(@Nullable Result result) {
      this.taskBLock.setResultAndNotify(result);
  }
  </code></pre>
  
  <p>Useful, right ? Granted, the wait for ever is no ideal.</p>
  
  <h2>Migrating to Kotlin</h2>
  
  <p>Now I am developing in Kotlin and I have started to read about concurrency and coroutines.
  There was one article, at some point, converting Java's synchronisation / lock / wait / notify pattern into Kotlin which helped me translated my original class to that:</p>
  
  <h2>Lock.kt</h2>
  
  <pre><code>import android.util.Log
  
  class Lock&lt;T&gt; {
  
      private var result : T? = null
  
      private var isWaiting = false
      private var wasNotified = false
  
      private val lock = Object() // Java object, Urgh...
  
      fun setResultAndNotify(value: T?) {
          result = value
          if (isWaiting) {
              synchronized(lock) {
                  lock.notify()
              }
          } else {
              wasNotified = true
          }
      }
  
  
      fun waitAndGetResult(timeout: Long) : T? {
          if (wasNotified) {
              wasNotified = false
              return result
          }
  
          try {
              synchronized(lock) {
                  isWaiting = true
                  if (timeout &lt; 0) lock.wait() else lock.wait(timeout)
                  isWaiting = false
              }
          } catch (e: InterruptedException) {
              Log.getStackTraceString(e)
          }
  
          return this.result
      }
  
  
      fun waitAndGetResult() = waitAndGetResult(-1)
  }
  </code></pre>
  
  <p>And no problem here it does work... But, it's Kotlin! Surely I could do better ?
  What would be your solution ?</p>