信号量

信号量(Semaphore)

信号量是限制并发线程数的一种方法,广义上,信号量是对锁的扩展。不同于synchronized和ReentrantLock,synchronized和ReentrantLock限制单次只允许一个线程访问一个资源,而信号量则可以指定单次有多少个线程访问一个资源。
Semaphore提供两个构造器:

public Semaphore(int permits);

public Semaphore(int permits,boolean fair) 
// fair可以指定是否公平

主要包含如下方法:

public void acquire();
public void acquireUninterruptibly()
public boolean tryAcquire()
public boolean tryAcquire(long timeout,TimeUnit unit)
public void release();

acquire();

尝试获得一个准入许可,若无法获得,则线程会等待,直到有线程释放一个许可或当前线程被中断。

acquireUninterruptibly()

效果和acquire类似,但是不响应线程中断

tryAcquire()

尝试获得一个许可,如果成功返回true,失败返回false。不会等待,立即返回(可以通过传入timeout和unit设置等待时间,unit为时间单位)

release()

当线程获得许可进入资源并处理完后,需要通过调用release方法释放许可,以便让其他等待进入许可的线程可以获取许可并访问资源。

简单的demo如下

package com.cn.demo.semp;

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

public class SempDemo implements Runnable {
    // 以公平方式允许五个线程同时访问指定资源
    final Semaphore semp = new Semaphore(5, true);

    @Override
    public void run() {
        try {
            semp.acquire();
            // 模拟耗时的业务逻辑
            Thread.sleep(5000);
            System.out.println("线程" + Thread.currentThread().getName() + "执行完毕!");
            semp.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        final SempDemo sempDemo = new SempDemo();
        for (int i = 0; i < 20; i++) {
            executor.execute(sempDemo);
        }
    }
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×