在spring cloud的hystrix组件中资源隔离分为线程池隔离和信号量,信号量底层用的就是Semaphore,下面分析Semaphore使用
public class Semaphore1{
public static void main(String[] args){
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
//分配2个信号量,不代表两个线程同时执行,因为一个线程可以拥有多个信号量
Semaphore semaphore = new Semaphore(2);
for(int i = 0; i < 10; i++){
new Thread(new Task(semaphore),"threadname"+i).start();
}
}
static class Task extends Thread{
Semaphore semaphored;
public Task(Semaphore semaphored){
this.semaphored = semaphored;
}
@Override
public void run(){
try{
//获取信号量,默认是一个
semaphored.acquire();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
//释放信号量,默认是一个
semaphored.release();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public class Semaphore2{
public static void main(String[] args){
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
//分配3个信号量,不代表3个线程同时执行,因为一个线程可以拥有多个信号量
Semaphore semaphore = new Semaphore(3);
for(int i = 0; i < 10; i++){
new Thread(new Task(semaphore),"threadname"+i).start();
}
}
static class Task extends Thread{
Semaphore semaphored;
public Task(Semaphore semaphored){
this.semaphored = semaphored;
}
@Override
public void run(){
try{
//每次获取两个信号量
semaphored.acquire(2);
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
//获取信号量和释放信号量要保持一直,因为在AbstractQueuedSynchronizer类中维护了一个成员变量 state,这里为3,减去acquire中的入参和加release的入参,如果两个入参不一致,
// 减掉的和加上的数值不同,导致信号量前后不对等
semaphored.release(2);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public class Semaphore3{
public static void main(String[] args){
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
//分配3个信号量,不代表3个线程同时执行,因为一个线程可以拥有多个信号量
Semaphore semaphore = new Semaphore(3);
for(int i = 0; i < 10; i++){
new Thread(new Task(semaphore),"threadname"+i).start();
}
}
static class Task extends Thread{
Semaphore semaphored;
public Task(Semaphore semaphored){
this.semaphored = semaphored;
}
@Override
public void run(){
try{
//返回是否有足够的信号量,并占用2个信号量,但是并不会阻塞其余信号量不足的线程
System.out.println(semaphored.tryAcquire(2));
Thread.sleep(1000);
//返还信号量
semaphored.release(2);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public class Semaphore4{
public static void main(String[] args){
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
//同一时间只允许3个线程执行
Semaphore semaphore = new Semaphore(2);
for(int i = 0; i < 10; i++){
new Thread(new Task(semaphore), "threadname" + i).start();
}
}
static class Task extends Thread{
Semaphore semaphored;
public Task(Semaphore semaphored){
this.semaphored = semaphored;
}
@Override
public void run(){
try{
//判断是否有足够的信号量,如果没有则等待500毫秒,500毫秒以后返回fase,并不会占用信号量,如果信号量够用则占用两个信号量,一定要返还
if(semaphored.tryAcquire(2, 500, TimeUnit.MILLISECONDS)){
//这里最好用finally保证释放信号量
try{
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
}finally{
//返还信号量
semaphored.release(2);
}
}else{
System.out.println(Thread.currentThread().getName() + "等待500毫秒之后取消等待");
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
网友评论