Open In App

Semaphores in Kotlin

Semaphore is a set of permits. Assume it as a box that has the tokens(permits) for attending(performing) a task. Threads have access to Semaphore but not those permits. Depending on the number of permits, and when a thread arrives at the semaphore, a permit is given. If a Thread arrives when there are no permits available, it has to wait until a permit is assigned to it. Only then a task can be performed.

So basically, A Semaphore is used in Multi-Threading or a Multi-Threaded application. There can be multiple processes running in an application. The use of Semaphore is to restrict or control access to any common resource by multiple threads(processes). Semaphore by definition is used for signaling from one task to another. They allow flexible source management.



Visualization of Multi-Threaded process using a Semaphore

  1. Threads arriving at Semaphore for the resources.
  2. Semaphore assigning Permits to the Threads and halts the rest of the Threads if falls short of Permits. The process of assigning Permit to a Thread is called Acquiring.
  3. Previously running Threads release the Permits when the task is completed. These Permits are now assigned to the halted Threads. This process where the Threads submit back the Permit is called Releasing.

The program below is in Kotlin, an example where a Semaphore is used for running some activity in a Multi-Threaded process:




import java.util.concurrent.Semaphore
  
val s = Semaphore(2)
  
val t1 = Thread(Runnable 
{
    s.acquireUninterruptibly()
    print("t1")
    Thread.sleep(10000)
    print(".")
    s.release()
})
  
val t2 = Thread(Runnable 
{
    s.acquireUninterruptibly()
    print("t2")
    Thread.sleep(10000)
    print(".")
    s.release()
})
  
val t3 = Thread(Runnable 
{
    s.acquireUninterruptibly()
    print("t3")
    Thread.sleep(10000)
    print(".")
    s.release()
})
  
val t4 = Thread(Runnable 
{
    s.acquireUninterruptibly()
    print("t4")
    Thread.sleep(10000)
    print(".")
    s.release()
})
  
  
t1.start()
t2.start()
t3.start()
t4.start()

Output:



t1t2..t3t4..

Here 2 dots i.e. in the output “..” represents 10 seconds wait(Thread.sleep) between permit acquire and permit release.

Note: Setting Priority to the Threads is possible. In such a case, the Threads are in Priority order and likewise, Permits are assigned to them. Multiple Semaphores can be declared depending upon the number of resources required by the process.


Article Tags :