Semaphore

我们先来学习一下JDK1.5 API中关于这个类的详细介绍: 
“一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。” 

    我们一般用它来控制某个对象的线程访问对象 

    例如,对于某个容器,我们规定,最多只能容纳n个线程同时操作 

使用信号量来模拟实现 


Test用例如下(目的是利用信号量来控制set集合中最多只包含三个元素,其中syn关键字只是为了能够直观的观测到结果添加的,如果不需要观测set集合的大小可以去掉提高性能):

package concurrentTest;                                         
                                                                
import java.util.Collections;                                   
import java.util.HashSet;                                       
import java.util.Set;                                           
import java.util.concurrent.ExecutorService;                    
import java.util.concurrent.Executors;                          
import java.util.concurrent.Semaphore;                          
                                                                
public class TestSemaphore {                                    
                                                                
    public static void main(String[] args) {                    
        ExecutorService exec = Executors.newCachedThreadPool(); 
        TestSemaphore t = new TestSemaphore();                  
        final BoundedHashSet<String> set = t.getSet();          
                                                                
        for (int i = 0; i < 20; i++) {//三个线程同时操作add             
            exec.execute(new Runnable() {                       
                public void run() {                             
                    try {                                       
                        set.add(Thread.currentThread().getName()
                        Thread.sleep(500);                      
                        set.remove(Thread.currentThread().getNam
                    } catch (InterruptedException e) {          
                        e.printStackTrace();                    
                    }                                           
                }                                               
            });                                                 
        }                                                       
                                                                
//        for (int j = 0; j < 4; j++) {//三个线程同时操作remove         
//            exec.execute(new Runnable() {                     
//                public void run() {                           
//                    set.remove(Thread.currentThread().getName(
//                }                                             
//            });                                               
//        }                                                     
        exec.shutdown();                                        
    }                                                           
                                                                
    public BoundedHashSet<String> getSet() {                    
        return new BoundedHashSet<String>(3);//定义一个边界约束为2的线程    
    }                                                           
                                                                
    class BoundedHashSet<T> {                                   
        private final Set<T> set;                               
        private final Semaphore semaphore;                      
                                                                
        public BoundedHashSet(int bound) {                      
            this.set = Collections.synchronizedSet(new HashSet<T
            this.semaphore = new Semaphore(bound, true);        
        }                                                       
                                                                
        public void add(T o) throws InterruptedException {      
            semaphore.acquire();//信号量控制可访问的线程数目                 
            set.add(o);                                         
            synchronized (this) {                               
                System.out.println(set.size());                 
            }                                                   
            System.out.printf("add:%s%n",o);                    
        }                                                       
                                                                
        public synchronized void remove(T o) {                  
            synchronized (this) {                               
                if (set.remove(o))                              
                    semaphore.release();//释放掉信号量                
            }                                                   
            System.out.printf("remove:%s%n",o);                 
        }                                                       
    }                                                           
}                                                               


输出如下:

1
2
add:pool-1-thread-2
add:pool-1-thread-1
3
add:pool-1-thread-3
remove:pool-1-thread-2
3
add:pool-1-thread-4
remove:pool-1-thread-3
remove:pool-1-thread-1
3
add:pool-1-thread-6
3
add:pool-1-thread-5
remove:pool-1-thread-5
3
add:pool-1-thread-7
remove:pool-1-thread-4
remove:pool-1-thread-6
3
add:pool-1-thread-9
3
add:pool-1-thread-8
remove:pool-1-thread-7
3
add:pool-1-thread-10
remove:pool-1-thread-8
remove:pool-1-thread-9
3
add:pool-1-thread-12
3
add:pool-1-thread-11
remove:pool-1-thread-10
3
add:pool-1-thread-13
remove:pool-1-thread-12
remove:pool-1-thread-11
3
add:pool-1-thread-15
3
add:pool-1-thread-14
remove:pool-1-thread-15
remove:pool-1-thread-14
3
add:pool-1-thread-16
remove:pool-1-thread-13
3
add:pool-1-thread-18
3
add:pool-1-thread-17
remove:pool-1-thread-18
3
add:pool-1-thread-19
remove:pool-1-thread-17
remove:pool-1-thread-16
2
add:pool-1-thread-20
remove:pool-1-thread-20
remove:pool-1-thread-19


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值