一个简单的Java信号量例子

 

一个简单的Java信号量例子

2010-12-20 星期一 晴朗

最近搞个CRM搜索排序服务工具,需要在对searchweb的调用接口作并发量控制(每天机器最多允许20个并发)。信号量最能作这种事情了。于是写了这么一个程序:

com.alibaba.intl.moree.app.business.product.search.ProductSearchServiceImpl
// 每台moree机器只运行20个并发
    private static final int                      MAX_ALLOW_CONCURRENCY    = 20;
    private static final Semaphore                semp                     = new Semaphore(MAX_ALLOW_CONCURRENCY);

 public SearchResultDTO search(String queryString, int pageSize, int pageIndex, String clientIPAddress) {
        DefaultProductSearchRequest productSearchReq = ProductSearchUtil.constructDefaultProductSearchRequest(queryString,
                                                                                                              pageSize,
                                                                                                              pageIndex,
                                                                                                              DefaultProductSearchRequest.VIEWMODE_DETAIL,
                                                                                                              clientIPAddress);
        ProductSearchResult searchResult = null;
        boolean serviceAvailable = false;
        try {
            int toWait = ProductSearchUtil.getRamdonIntValue(100);
            serviceAvailable = semp.tryAcquire(toWait, TimeUnit.MICROSECONDS);
            if (!serviceAvailable) {
                return null;
            }
            searchResult = backProductSearchService.search(productSearchReq);
        } catch (InterruptedException e) {
            log.error(e);
            return null;
        } finally {
            if (serviceAvailable) {
                semp.release();
            }
        }
        if (searchResult == null || searchResult.getProductSearchDOList() == null
            || searchResult.getProductSearchDOList().isEmpty()) {
            return new SearchResultDTO();
        }
        return toSearchResultDTO(pageSize, pageIndex, searchResult);
    }

再写了一个单元测试测试一下:

com.alibaba.intl.moree.app.business.product.search.ProductSearchServiceImplTest
@Test
    public void testSearchForSempaphore() {
        List<Future<?>> futureList = new ArrayList<Future<?>>();
        // 起100个线程
        ExecutorService es = Executors.newFixedThreadPool(100);
        // 创建100个任务
        for (int i = 0; i < 100; i++) {
            final int index = i;
            futureList.add(es.submit(new Callable<Object>() {

                public Object call() throws Exception {
                    // String queryString = "power strip";
                    String queryString = "mp3";
                    int pageSize = 38;
                    int pageIndex = 1;
                    String clientIpAddr = "127.0.0.1";

                    SearchResultDTO searchResult = productSearchService.search(queryString, pageSize, pageIndex,
                                                                               clientIpAddr);

                    if (searchResult == null) {
                        System.err.println(">>>>>>>>>>>No Result: " + index + ": " + System.nanoTime() + "<<<<<<<<<<<<<");
                    } else {
                        System.err.println(">>>>>>>>>>>Got it: " + index + ": " + System.nanoTime() + "<<<<<<<<<<<<<");
                    }
                    return searchResult;
                }
            }));
        }
    }

测试结果如下:

>>>>>>>>>>>No Result: 21:43083593995477<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 22:43083594747712<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 0:43083594990254<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 25:43083595250057<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 26:43083595395360<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 27:43083595606066<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 28:43083595803244<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 30:43083597044662<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 31:43083597303884<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 34:43083597663030<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 38:43083598426741<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 23:43083598569064<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 40:43083598727475<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 41:43083599057380<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 37:43083600240167<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 36:43083600305847<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 35:43083600370916<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 33:43083600454055<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 32:43083600573838<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 29:43083601107023<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 24:43083601167615<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 39:43083623270627<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 69:43083623527384<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 62:43083623744850<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 67:43083623922262<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 66:43083623956991<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 65:43083623991809<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 61:43083624025479<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 58:43083624038951<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 64:43083624056136<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 57:43083624105761<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 48:43083624322451<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 44:43083624470016<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 51:43083624530993<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 55:43083624565974<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 45:43083624596561<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 53:43083624626614<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 43:43083624656197<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 49:43083624686487<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 47:43083624716753<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 54:43083624746330<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 52:43083624776900<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 63:43083624807460<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 46:43083624837383<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 50:43083624867318<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 70:43083624897632<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 71:43083624928067<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 56:43083624989516<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 60:43083625021258<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 59:43083623991521<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 74:43083625606070<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 75:43083625831629<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 76:43083625970584<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 78:43083626275724<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 80:43083629144739<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 81:43083629388929<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 42:43083630588618<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 68:43083630632729<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 82:43083630679269<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 84:43083632884616<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 87:43083633159826<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 86:43083633215721<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 88:43083633560364<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 89:43083633696893<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 90:43083633863152<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 91:43083634039314<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 92:43083634173464<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 94:43083634478468<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 95:43083634594372<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 96:43083634770362<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 97:43083634959156<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 98:43083635126501<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 99:43083635366066<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 77:43083639285498<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 72:43083639317126<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 73:43083639293984<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 93:43083639391063<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 83:43083639432777<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 85:43083639433441<<<<<<<<<<<<<
>>>>>>>>>>>No Result: 79:43083644641209<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 17:43087061266900<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 19:43087065884586<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 20:43087091836718<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 4:43087098653438<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 16:43087100980919<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 6:43087140846243<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 5:43087150381332<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 1:43087155102190<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 12:43087184410436<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 8:43087193385816<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 18:43087203357940<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 11:43087272986713<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 10:43087295791193<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 15:43087732087345<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 14:43088029861445<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 2:43088087667651<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 7:43088096323181<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 3:43088919799352<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 9:43089587083905<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 13:43089595166046<<<<<<<<<<<<<

跑了好几次,奇怪的是每次都是只有20条成功。非常固定。

后来从代码重构的角度将并发量控制从上面的方法中抽取出来,成为一个独立的似有函数,再跑单元测试,发现一个非常诡异的现象:

com.alibaba.intl.moree.app.business.product.search.ProductSearchServiceImpl
// 每台moree机器只运行20个并发
    private static final int                      MAX_ALLOW_CONCURRENCY    = 20;
    private static final Semaphore                semp                     = new Semaphore(MAX_ALLOW_CONCURRENCY);

 public SearchResultDTO search(String queryString, int pageSize, int pageIndex, String clientIPAddress) {
        DefaultProductSearchRequest productSearchReq = ProductSearchUtil.constructDefaultProductSearchRequest(queryString,
                                                                                                              pageSize,
                                                                                                              pageIndex,
                                                                                                              DefaultProductSearchRequest.VIEWMODE_DETAIL,
                                                                                                              clientIPAddress);
        ProductSearchResult searchResult = innerSearch(productSearchReq);

        if (searchResult == null || searchResult.getProductSearchDOList() == null
            || searchResult.getProductSearchDOList().isEmpty()) {
            return new SearchResultDTO();
        }
        return toSearchResultDTO(pageSize, pageIndex, searchResult);
    }

    private ProductSearchResult innerSearch(ProductSearchRequest productSearchReq) {
        boolean serviceAvailable = false;
        try {
            int toWait = ProductSearchUtil.getRamdonIntValue(100);
            serviceAvailable = semp.tryAcquire(toWait, TimeUnit.MICROSECONDS);
            if (!serviceAvailable) {
                return null;
            }
            ProductSearchResult searchResult = backProductSearchService.search(productSearchReq);
            return searchResult;
        } catch (InterruptedException e) {
            log.error(e);
            return null;
        } finally {
            if (serviceAvailable) {
                semp.release();
            }
        }
    }

代码好看多了吧,再看看单元测试跑出来的结果:

>>>>>>>>>>>Got it: 69:43362814956985<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 9:43362815018425<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 13:43362815077525<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 68:43362815094061<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 8:43362815118893<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 5:43362815155212<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 2:43362815189507<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 1:43362815223737<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 7:43362815006087<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 67:43362815267125<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 66:43362815289723<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 36:43362815303095<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 14:43362815338672<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 3:43362814957120<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 11:43362815397186<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 10:43362815430807<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 6:43362815463683<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 12:43362815495964<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 4:43362815528437<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 16:43362815561211<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 58:43362815597903<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 59:43362815631512<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 0:43362815665630<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 37:43362815699273<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 61:43362815733241<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 20:43362815766682<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 18:43362815802120<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 60:43362815837050<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 17:43362815871658<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 31:43362815906987<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 57:43362815941123<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 56:43362815975253<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 25:43362816010736<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 23:43362816045263<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 33:43362816080719<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 38:43362816114825<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 22:43362816149412<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 29:43362816271991<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 28:43362816307372<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 19:43362816342368<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 27:43362816376970<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 24:43362816412462<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 30:43362816447088<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 21:43362816483227<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 26:43362816519504<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 15:43362815345913<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 71:43362816940237<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 72:43362817224288<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 73:43362817301954<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 74:43362817455617<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 75:43362817738423<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 76:43362817815683<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 77:43362818011637<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 78:43362818120315<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 79:43362818291623<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 80:43362818497250<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 81:43362818687416<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 82:43362818924635<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 83:43362818972489<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 84:43362819192292<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 85:43362819417673<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 86:43362819601210<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 87:43362819877329<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 88:43362819930749<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 89:43362820110690<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 70:43362821251337<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 90:43362824707195<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 91:43362826002020<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 92:43362826319308<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 93:43362826382730<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 94:43362826562036<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 95:43362826752120<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 96:43362827255556<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 97:43362827290299<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 98:43362827891419<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 63:43362827908628<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 62:43362827952308<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 64:43362828025048<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 65:43362831012315<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 99:43362832259608<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 44:43366220882488<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 47:43366248763967<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 35:43366248820234<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 54:43366249829734<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 50:43366269035348<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 43:43366278322371<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 53:43366278787534<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 40:43366305676516<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 32:43366312615671<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 39:43366388045184<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 41:43366539667837<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 49:43366704070031<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 46:43367078320751<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 34:43367095009813<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 48:43367134647760<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 52:43367296257307<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 45:43368169702377<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 51:43368260309923<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 55:43368270676948<<<<<<<<<<<<<
>>>>>>>>>>>Got it: 42:43368271083157<<<<<<<<<<<<<

连续跑N次,每次都是100%通过。非常诡异。具体原因,明天再看吧,夜了。

 

补记:第二天再跑发现两者结果又是一样了,诡异现象不见了。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值