Java-多线程

Semaphore 多线程并发控制

2020-04-14  本文已影响0人  PageThinker
1.png

01 Semaphore

Semaphore 的作用就是控制某段程序线程并发执行的数量。这比 sychronized 功能更加强大和方便。

Semaphore 有个一个参数为 permits 的构造函数。(permist 指的是同一时间内允许多少个线程同时执行 acquire()和 release()之间的代码。

...
private final Semaphore semaphore = new Semaphore(1);
...
public void work() {
    ...
    semaphore.acquire();
    ...
    semaphore.relose();
    ...
}

Semaphore 只能控制共用一个 Semaphore 对象的线程时间的同步。 不同 semaphore 之间的线程时无法控制的。

02 Semaphore 中的常用方法

构造函数参数 permits,通过构造参数指定许可证数量。

acquire(): 使用构造函数中的 permits 中的值,限制线程执行 acquire和release 之间的线程数。

acquire(int permits) 每执行一次从 初始化的 permits 申请 x 个认证数,申请了 x 个必须 release x 个证书才能继续向下执行。

acquireUninterruptibly() 使进入 acquire()方法线程,不允许被中断。

availablePermits() 返回当前可用的许可数。

drainPermits() 返回当前可用的许可数,并将许可数设置为 0

getQueueLength() 取得等待许可的线程数

hasQueueLength() 判断有没有线程在等待这个许可。

tryAcquire() 尝试获取一个许可,若获取不到则返回 false,此方法通常与 if 结合,具有无阻塞的特点(即不需要在等待处一直等待),若 if 不成立则直接返回 else 语句。

tryAcquire(int permits) 尝试获取 permits 个许可,若获取不到则返回 false

tryAcquire(long timeout, TimeUnit unit) 在制定的实现内获取 1 个许可

tryAcquire(int permits, long timeout, TimeUnit unit) 尝试在指定的时间内获取 permits 个许可。

2.png

03 公平和非公平信号量

公平信号量:获得锁的顺序与线程执行的顺序有关。

非公平信号量:获得锁的顺序与线程执行的顺序无关。

04 扩展

(1)线程和 CPU 之间的关系。

线程过多会导致 CPU 资源被耗尽,每个线程执行过程都相当缓慢,因为 CPU 除了把时间片段分配给了不同的线程,在切换不同上下文时也是需要时间的,因此线程数过多会导致系统性能大幅降低。

(2)多线程同步

多线程同步指的是排队执行某一任务,执行的任务是一个个去执行的,并不能并行。

(3)缺点

permits 增加了控制的难度。

例如,创建 Semaphore 是指定的 permits 的数量为 1, 但是执行 semaphore.acquire(2) 时指定要申请的 permits 数量为 2,总共的许可数有 1 个,但是申请 2 个,那么程序就会 block 住,因为当许可不够时,就会一直等待,使用 semephore 对象的任何线程都会阻塞。

private Semaphore semaphore = new Semaphore(1);

private void method() {
        semaphore.acquire(2); // 由于只有一个 1 个证书可申请,因此会一直阻塞。
        ...
        semaphore.release(2);
}

同样会造成 block 的情况还有一种情况,当执行 semaphore.acquire(3) 申请了两个许可证,但是后续 只执行了一次 semaphore.release() 操作或者执行的 release 许可证的的数量小于3,那么同样会造成 block。

private Semaphore semaphore = new Semaphore(2);
...

public void method() {
    semaphore.acquire(2);
    ...
    semaphore.release(); // 只 release 了一个证书,还需在执行一次 release 或者 release 执行证书数为 2
}

(4)permits 指定数量带来的扩展

Semaphore 可以有效的对并发执的数量进行控制,因此可以应用在多个场景下。

(1)同步操作。同一时间只能由一个线程进行操作。

(2)动态调整性能。根据 CPU 的负载情况,动态调整当前任务并行处理的线程数。

上一篇下一篇

猜你喜欢

热点阅读