Semaphore control the number of concurrent threads

I. Introduction and construction methods

Semaphore(Semaphore) is used to control access to specific resources while the number of threads . It is through the coordination of the various threads , in order to ensure rational use of public resources .


Second, the construction method:

public Semaphore(int permits)

public Semaphore(int permits, boolean fair)

Wherein the second constructor in the second parameterfair can specify whether fair


In constructing the semaphore object, you must specify the number of wash admission that while the number of licenses can apply.

When each thread to apply for a license, which is equivalent to specify how many simultaneous threads can access a resource.


Third, the method of the main logic semaphore

public void acquire()

public void acquireUninterruptibly()

public boolean tryAcquire()

public boolean tryAcquire(long timeout, TimeUnit unit)

public void release()

Specific Usage:

acquire()The method of trying to get an access license . If unable to obtain , the thread will wait until the thread releases a license or the current thread is interrupted

acquireUninterruptibly()Methods and acquire()methods similar to , but does not respond to interrupts .

tryAcquire()The method attempts to obtain a license , if the return is successful to true , failed to return false, it will not wait

release()The method used to release a license after the end of the thread to access a resource , so that other threads may be waiting for permission to access the resource.


Examples are as follows:

import java.util.concurrent.*;

public class SemaphoreTest implements Runnable {
	
	final Semaphore semp = new Semaphore(5);
	
	@Override
	public void run() {
		try {
			semp.acquire();
			Thread.sleep(1000);
			System.out.println(Thread.currentThread().getId() + ":done!");
		}catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			semp.release();
		}
	}

	public static void main(String[] args) {
		ExecutorService exec = Executors.newFixedThreadPool(20);
		SemaphoreTest semp = new SemaphoreTest();
		for(int i = 0; i < 20; i ++) {
			exec.submit(semp);
		}
	}

}复制代码

Note: Application semaphore used acquire()method of operation, the departure time, be sure to userelease() the method to release the semaphore .

This release and a lock token, if the unfortunate event of a semaphore leak ( applied for but not released ), you can enter the number of threads in the critical area will be less and less, until all the threads are inaccessible.


Fourth, the use of semaphores in order to complete the print output multithreaded

Requirements: three threads are sequentially printed out cycles a, b, c, d, e, f, g, h, i, i.e. the print thread 1 a, d, g; print thread 2 b, e, h; Thread Print 3 c, f, i.

import java.util.concurrent.*;

public class SemaphoreTest2 {
	
	static Semaphore semp1 = new Semaphore(1);
	static Semaphore semp2 = new Semaphore(1);
	static Semaphore semp3 = new Semaphore(1);
	static int n = 3;
	
	static class runnable1 implements Runnable {
		@Override
		public void run() {
			char beginChar = 'a';
			for(int i = 0; i < n; i ++) {
				try {
					if(i == 0) {
						System.out.println((char)(beginChar + i * 3));
						semp2.release();
					}else {
						semp1.acquire();
						System.out.println((char)(beginChar + i * 3));
						semp2.release();
					}
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	static class runnable2 implements Runnable {
		@Override
		public void run() {
			char beginChar = 'b';
			for(int i = 0; i < n; i ++) {
				try {
					semp2.acquire();
					System.out.println((char)(beginChar + i * 3));
					semp3.release();
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	static class runnable3 implements Runnable {
		@Override
		public void run() {
			char beginChar = 'c';
			for(int i = 0; i < n; i ++) {
				try {
					if(i == n - 1) {
						semp3.acquire();
						System.out.println((char)(beginChar + i * 3));
					}else {
						semp3.acquire();
						System.out.println((char)(beginChar + i * 3));
						semp1.release();
					}
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void main(String[] args) {
		try {
			semp1.acquire();
			semp2.acquire();
			semp3.acquire();
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		Thread thread1 = new Thread(new runnable1());
		Thread thread2 = new Thread(new runnable2());
		Thread thread3 = new Thread(new runnable3());
		thread1.start();
		thread2.start();
		thread3.start();
	}

}
复制代码


Guess you like

Origin juejin.im/post/5de3b97151882516e524b560