Java Multithreading: Semaphores (Video Tutorial Part 12)

A tutorial on semaphores in Java. Semaphores are mainly used to limit the number of simultaneous threads that can access a resources, but you can also use them to implement deadlock recovery systems since a semaphore with one permit is basically a lock that you can unlock from other threads. In this video we'll take a look at the most important methods of the Semaphore class, and I'll also show you an example of limiting the number of "connections" that threads can make simultaneously.

After starting the video, click the maximise button to make it fullscreen so you can see the code!



Code For This Tutorial



Current connections: 1
Current connections: 2
Current connections: 3
Current connections: 4
Current connections: 5
Current connections: 6
Current connections: 7
Current connections: 8
Current connections: 9
Current connections: 10
Current connections: 9
Current connections: 9
Current connections: 9
Current connections: 10
Current connections: 10
Current connections: 9
Current connections: 7
Current connections: 8
Current connections: 9
Current connections: 10




Connection.java: shows how to limit 'connections' with a semaphore

 
import java.util.concurrent.Semaphore;

public class Connection {

    private static Connection instance = new Connection();

    private Semaphore sem = new Semaphore(10, true);

    private int connections = 0;

    private Connection() {

    }

    public static Connection getInstance() {
        return instance;
    }

    public void connect() {
        try {
            sem.acquire();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        try {
            doConnect();
        } finally {

            sem.release();
        }
    }

    public void doConnect() {

        synchronized (this) {
            connections++;
            System.out.println("Current connections: " + connections);
        }

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        synchronized (this) {
            connections--;
        }

    }
}

 

App.java: creates 200 threads and fires them off simultaneously. They all try to run the connect() method of the Connection class at the same time.

 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;




public class App {

    public static void main(String[] args) throws Exception {
        
        ExecutorService executor = Executors.newCachedThreadPool();
        
        for(int i=0; i < 200; i++) {
            executor.submit(new Runnable() {
                public void run() {
                    Connection.getInstance().connect();
                }
            });
        }
        
        executor.shutdown();
        
        executor.awaitTermination(1, TimeUnit.DAYS);
    }

}