线程(八)---Semaphore

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!  

概念:

Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。从概念上讲,Semaphore是一个计数信号量,Semaphore包含一组许可证。

如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证。每个release()方法都会释放持有许可证的线程,并且归还Semaphore一个可用的许可证。

使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

Semaphore 是 synchronized 的加强版,作用是控制同时访问资源的线程个数(控制线程的并发数量)
当Semaphore初始值为1时其实就相当于 synchronized。

常用方法:

1.Semaphore(permits)

   初始化许可证数量的构造函数。

2.Semaphore(permits,fair)

   初始化许可证数量和是否公平模式的构造函数。

3.availablePermits()

   获取当前可用的许可证数量。

4.acquire()

   当前线程尝试去获取1个许可证。直到发生以下任意一件事:

   1):当前线程获取了1个可用的许可证,则会停止等待,继续执行。
   2):当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。

5.acquire(permits)

   当前线程尝试去获取permits个许可证。直到发生以下任意一件事:

   1):当前线程获取了permits个可用的许可证,则会停止等待,继续执行。
   2):当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。

6.tryAcquire()

   当前线程尝试去获取1个许可证。

   1):如果当前线程获取了1个可用的许可证,则会停止等待,继续执行,并返回true。

   2):如果当前线程没有获得这个许可证,也会停止等待,继续执行,并返回false。

7.tryAcquire(permits)

   当前线程尝试去获取permits个许可证。

   1):如果当前线程获取了permits个可用的许可证,则会停止等待,继续执行,并返回true。

   2):如果当前线程没有获得permits个许可证,也会停止等待,继续执行,并返回false。

8.tryAcquire(timeout,TimeUnit)

   当前线程在限定时间内,尝试去获取1个许可证。直到发生以下任意一件事:

   1):当前线程获取了可用的许可证,则会停止等待,继续执行,并返回true。

   2):当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。

   3):当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。

9.tryAcquire(permits,timeout,TimeUnit)

   当前线程在限定时间内,尝试去获取permits个许可证。直到发生以下任意一件事:

   1):当前线程获取了可用的permits个许可证,则会停止等待,继续执行,并返回true。

   2):当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。

   3):当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。

10.release()

   当前线程释放1个可用的许可证。

11.release(permits)

   当前线程释放permits个可用的许可证。

因为平时用的不多,就简单举例记录一下,这个例子包含3个类,一个是线程类,一个是 线程要操作的资源类,一个类是主main方法类:

代码如下:

public class SemaphoreTest {


    public static void main(String[] args) {
        DoSomething doSomething = new DoSomething();
        for (int i=0;i<10;i++){
            Task t = new Task(doSomething);
            t.start();
        }
    }

    static class DoSomething{

        Semaphore semaphore = new Semaphore(2);

        public void doSome(){
            try {
                semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + ":开始任务");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + ":完成任务");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Task extends Thread{

        private DoSomething doSomething;

        public Task(DoSomething doSomething){
            this.doSomething = doSomething;
        }

        @Override
        public void run() {
            doSomething.doSome();
        }
    }


}

执行结果如下:

线程(八)---Semaphore_第1张图片

可以看出:每次只能有两个线程并行执行,正如前面所说,它的作用就是控制同时访问资源的线程个数,一次只允许permits个线程访问。

 

你可能感兴趣的:(线程(八)---Semaphore)