Semaphore类
- 作用:限制线程并发的数量。
- 常用API
1-1:semaphore(int permits)创建一个Semaphore与给定数量的许可证
1-2:acquire(int permits)或者acquire() 获取一个或者permits个许可
1-3:release(int premits)或release()释放一个或者permits个许可,也可以动态增加permits个数
例子:
线程执行类:
package com.cjy;
import java.util.concurrent.Semaphore;
public class Service implements Runnable {
//定义semaphore;指定同时并发量有两个,(发布两个许可)
private Semaphore semaphore=new Semaphore(2);
@Override
public void run() {
try {
//使用其中一个许可
semaphore.acquire(1);
System.out.println(Thread.currentThread().getName()+"begin");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+"end");
//释放其中一个许可;
semaphore.release(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main类
package com.cjy;
public class Main {
public static void main(String[] args) throws InterruptedException {
Service service=new Service();
Thread t1= new Thread(service);
t1.setName("t1");
t1.start();
Thread t2 = new Thread(service);
t2 .setName("t2");
t2 .start();
Thread t3 = new Thread(service);
t3.setName("t3");
t3.start();
}
}
运行结果:
1-4:semaphore.availablePermits() 获得当前可用的许可数
1-5:acquire是可以被中断的,而acquireUninterruptibly()方法是 “在等待许可的情况下不允许中断”。
1-6:drainPermits() 可获得并返回立刻可用的所有许可个数,并将可用许可置为0
1-7:getQueueLength() 获取等待许可的线程个数
1-8:hasQueuedThreads() 判断是否有没有线程在等待许可
- 公平与非公平信号量的
4.1:公平信号量是:获得锁的顺序与线程启动的顺序有关。(先启动的线程先获得许可;只能在概率上保证有关)
4.2: 非公平信号量:线程启动的顺序与调用semaphore.acquire()顺序无关
4.3:semaphore构造方法中:
5.非阻塞获取许可
方法:
A: tryAcquire()或 tryAquire(long timeOut,TimeUnit timeUnit)
尝试的获取许可(1个),若获取不到则返回false。(带timeOut是在指定回见内尝试地获取锁)
B:tryAcquire(int permit)或 tryAcquire(int permit,long timeOut,TimeUnit timeUnit)
尝试的获取许可(permit个),若获取不到则返回false。(带timeOut是在指定回见内尝试地获取锁)
用法:用if语句,若获取不到,则继续走else语句,保证线程不会阻塞在那里。
Exchanger类
-
Exchanger是线程间交换信息的方法之一
-
通过exchange()方法向两个格子填充信息;
2-1:当两个格子中的均被填充时,该对象会自动将两个格子的信息交换,然后返回给线程,从而实现两个线程的信息交换 2-2:若没有其他线程取得数据,则一直阻塞等待。
-
API
3-1:exchange(String v): 像格子里面添加数据。 3-2:exchange(String v,long timeOut,TimeUnit timeunit): 像格子里面添加数据,若在timeout个单位时间内,没有其他线程取出,就会抛出TimeOutException异常
小节
- Semaphore类是用于控制线程并发个数的解决方法,通过许可数量进行操控
- Exchanger是线程间传输数据的方法之一;比喻为两个格子,线程利用exchange()方法向里面传送数据,若两个格子都有数据,则互换数据。若没有则无限阻塞等待或者有限时间内阻塞等待。