semaphore:
功能:限制线程并发的数量
使用场景:数据库连接只有10个,有100个线程需要获取连接,这个时候可以使用semaphore进行限流
方法摘要:
1)acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
2)release():
释放一个许可,将其返回给信号量。
3)availablePermits():
返回此信号量中当前可用的许可数。
4)hasQueuedThreads():
查询是否有线程正在等待获取。
public class SemaphoreTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
//创建Semaphore信号量,初始化许可大小为3
final Semaphore sp = new Semaphore(3);
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e2) {
e2.printStackTrace();
}
Runnable runnable = new Runnable() {
public void run() {
try {
///请求获得许可,如果有可获得的许可则继续往下执行,许可数减1。否则进入阻塞状态
sp.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "获得许可");
try {
Thread.sleep((long) (Math.random() * 10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "即将离开");
//释放许可,许可数加1
sp.release();
}
};
service.execute(runnable);
}
}
}
exchanger:
功能:线程间进行通信、数据交换
使用场景:当两个线程间需要交换数据,将本线程产出数据传递给对方时,可使用exchanger进行传输
方法摘要:
exchange():两个线程调用exchange方法,无论调用时间先后,线程会等待对方到达exchange方法调用点
public class ExchangerTest {
// Exchanger实例.
private static final Exchanger<String> exchanger = new Exchanger<String>();
public static void main(String[] args) {
new Thread(() -> {
try {
String b = "你也是";
System.out.println(Thread.currentThread().getName() + "准备就绪,准备发送数据" + b);
Thread.sleep(2000);
String s = exchanger.exchange(b);
System.out.println(Thread.currentThread().getName() + "接收数据" + s);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String s = "你真帅";
System.out.println(Thread.currentThread().getName() + "准备就绪,准备发送数据" + s);
Thread.sleep(4000);
String b = exchanger.exchange(s);
System.out.println(Thread.currentThread().getName() + "接收数据" + b);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}).start();
}
}