Java multithreaded Semaphore synchronization classes CountDownLatch and Semaphore

Keywords: Java Windows

Semaphore synchronization refers to the coordination of thread execution sequence by transferring synchronization semaphores between different threads. CountDownLatch is based on time dimension, semaphore is based on signal dimension.

1: Execution time based synchronization class CountDownLatch

For example, for the existing three servers, it is necessary to write an interface to obtain the state of each server, and prepare to open three sub threads to obtain the state of one server and return the state of three servers uniformly. The CountDownLatch instance with counter 3 is defined in the main thread. Each sub thread adds a CountDownLatch instance reference. After the execution of the sub thread, count down the CountDownLatch. The main thread calls the await method of CountDownLatch instance and waits for all the sub threads to finish executing before returning the result. An example of code that does not consider exceptions is as follows.

public class Main {

public static void main(String[] args) throws InterruptedException {
CountDownLatch count = new CountDownLatch(3);
Thread getServer1Status = new GetDataStatusThread("Server 1", count);
Thread getServer2Status = new GetDataStatusThread("Server 2", count);
Thread getServer3Status = new GetDataStatusThread("Server 3", count);

getServer1Status.start();
getServer2Status.start();
getServer3Status.start();

//await causes the current thread to wait until the count of CountDownLatch is 0, unless the thread is interrupted
//count.await();
//Wait (long timeout, timeunit unit) causes the current thread to wait until the count of CountDownLatch is 0, unless the thread is interrupted or the specified waiting time has passed
count.await(10,TimeUnit.SECONDS);
System.out.println("All server status acquisition completed");

}
}

class GetDataStatusThread extends Thread {

private final CountDownLatch count;

public GetDataStatusThread(String threadName, CountDownLatch count) {
this.setName(threadName);
this.count = count;
}

@Override
public void run() {
System.out.println("Obtain" + this.getName() + "State success");
//Decrements the count of CountDownLatch and releases all waiting threads if the count reaches zero
count.countDown();
}
}

Note: the await method of CountDownLatch recommends using the with timeout. Do not use a thread with timeout await. If the initial value of the counter is not set to countDown, the thread will wait until the count is 0, unless the thread is interrupted

(for example, if an exception occurs during the execution of a sub thread and the counter down method is not executed, by the way, it can be added that if the sub thread throws an exception and the exception is not caught by the main thread, it can be caught by the thread method setUncaughtExceptionHandler()).

2: Semaphore based on idle signal

Semaphore can be regarded as a pool to manage "licenses". When creating an instance of semaphore, the number of licenses is specified. All threads that contain the reference of the instance of semaphore obtain the licenses through the acquire method when running, and release the licenses through the release method after running. Threads such as get no license will not execute until get idle license. As shown in the following code: there are only two ticket buying windows (the size of the license pool) in a scenic spot. All tourists queue up to buy tickets. The tourists who are ready to buy tickets occupy the current window through acquire to buy tickets and are ready to leave. The current window is empty through release method.

 

public class Window {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);

        for (int i = 1; i <= 6; i++) {
            new ByTicketThread("Customer" + i, semaphore).start();
        }
    }

}

class ByTicketThread extends Thread {

    private final Semaphore semaphore;

    public ByTicketThread(String threadName, Semaphore semaphore) {
        this.setName(threadName);
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            semaphore.acquire();
            System.out.println(this.getName() + "Tickets are being bought.");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
            System.out.println(this.getName() + "The ticket is purchased.");
        }

    }
}

Posted by activomate on Wed, 05 Feb 2020 04:23:47 -0800