<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    線程池池

    Posted on 2008-09-01 19:38 dennis 閱讀(2396) 評論(2)  編輯  收藏 所屬分類: java
        這個題目比較怪,聽俺道來。俺一直在負責公司游戲服務器的開發和維護,日積月累下來終于將原本混亂的代碼和結構重構的比較清晰了,在此過程中的體會就是,重構啊,不僅僅是技術活,更多是要克服不情愿的、得過且過的心理去做,去做了才發現麻煩并沒有想象中的大。
        改造過程中遇到這么個問題,我想將對某個創建的游戲的操作都固定在一個線程執行,與其他游戲可以并發地處理;或者說依據游戲id派發到某個固定的線程處理,對此游戲的操作都是串行化。不是俺不想徹底并行化,但是要將現有的代碼改造成適應并行化相當困難,俺嘗試的結果是問題百出,因此就想了這么個折中策略,不同游戲之間的操作可以并行,單個游戲內操作串行。怎么派發呢?很簡單的機制,根據id%size結果來處理就好,size就是你準備開的線程數。因此可以很容易地模擬一個生產者消費者模型的線程池,根據游戲id%size的結果將任務塞到隊列中,讓生產者線程順序處理。已經有部分代碼是這樣處理的,不過是自己實現的模型(BlockingQueue),比較不適合俺想要的任務式的處理過程,靈機一動,jdk5引入的線程池不是有個單線程的版本嗎?俺將這個線程池再做個池不就OK了?說起來不好理解,看代碼:
    public interface Task extends Runnable {
        
    public int getCode();
    }
        嗯,定義一個Task接口,繼承Runnable,多了個getCode方法用于決定派發任務到哪個ExecutorService執行。線程池池登場:
    public class SingleThreadPoolPool {
        
    private Map<Integer, ExecutorService> threadPoolMap = new HashMap<Integer, ExecutorService>();

        
    private int size;

        
    public SingleThreadPoolPool(int size) {
            
    this.size = size;
            
    for (int i = 0; i < size; i++) {
                ExecutorService executor 
    = Executors.newSingleThreadExecutor();
                threadPoolMap.put(i, executor);
            }
        }

        
    public void execute(Task task) {
            
    if (task == null)
                
    return;
            threadPoolMap.get(getIndex(task.getCode())).execute(task);
        }

        
    public void execute(int code, Runnable r) {
            
    if (r == null)
                
    return;
            threadPoolMap.get(getIndex(code)).execute(r);
        }

        
    private int getIndex(int code) {
            
    int index = -1;
            
    if (code < 0)
                index 
    = 0;
            
    else
                index 
    = code % this.size;
            
    return index;
        }

        
    public void shutdown() {
            
    for (int i = 0; i < size; i++) {
                threadPoolMap.get(i).shutdown();
            }
            threadPoolMap.clear();
        }

        
    public int size() {
            
    return this.size;
        }
    }

        哇靠,這也太簡單了,這就能保證code相同的任務會被排隊順序執行。是啊,很簡單,不是啥高科技,但簡單明了地實現了俺的需求。需要注意的是,只有通過Executor的execute方法提交的任務才會被排到隊列中哦。
        補充一個線程安全測試:
    import java.util.concurrent.CountDownLatch;
    import com.xlands.game.lobby.util.SingleThreadPoolPool;

    import junit.framework.TestCase;

    class Counter {
        
    int i;

        
    public void incr() {
            i
    ++;
        }
    }

    class IncrTask implements Runnable {
        Counter counter;
        CountDownLatch latch;

        
    public IncrTask(Counter counter, CountDownLatch latch) {
            
    this.counter = counter;
            
    this.latch = latch;
        }

        
    public void run() {
            
    try {
                counter.incr();

            } 
    finally {
                latch.countDown();
            }
        }
    }

    public class SingleThreadPoolPoolTest extends TestCase {
        
    static final int NUM = 10000;
        SingleThreadPoolPool singleThreadPoolPool;

        @Override
        
    protected void setUp() throws Exception {
            singleThreadPoolPool 
    = new SingleThreadPoolPool(2);
            
    super.setUp();
        }

        @Override
        
    protected void tearDown() throws Exception {
            singleThreadPoolPool.shutdown();
            
    super.tearDown();
        }

        
    public void testThreadSafe() throws Exception {
            Counter c1 
    = new Counter();
            Counter c2 
    = new Counter();
            assertEquals(singleThreadPoolPool.size(), 
    2);
            CountDownLatch latch 
    = new CountDownLatch(NUM * 2);
            
    for (int i = 0; i < NUM; i++) {
                singleThreadPoolPool.execute(
    0new IncrTask(c1, latch));
                singleThreadPoolPool.execute(
    1new IncrTask(c2, latch));
            }
            latch.await();
            assertEquals(NUM, c1.i);
            assertEquals(NUM, c2.i);
        }
    }



    評論

    # re: 線程池池  回復  更多評論   

    2008-09-01 20:26 by 山風小子
    舊酒裝新瓶,呵呵 :)

    # re: 線程池池  回復  更多評論   

    2008-09-01 21:21 by YZ
    還不如你寫個簡單的游戲例子,教教我們得了!那樣來得更直觀,更有成就感!
    主站蜘蛛池模板: 日本阿v免费费视频完整版| 久久国产乱子免费精品| 在线a级毛片免费视频| 亚洲丝袜美腿视频| 98精品全国免费观看视频| 久久久久久久亚洲Av无码| 99ee6热久久免费精品6| 亚洲国产精品一区二区久久| 久久国产精品2020免费m3u8| 久久精品亚洲中文字幕无码麻豆| 在线观看的免费网站无遮挡| 亚洲一区二区三区在线| 成人免费无码大片a毛片软件| 亚洲熟妇无码一区二区三区导航| 精品国产精品久久一区免费式| 色噜噜噜噜亚洲第一| 国产人妖ts在线观看免费视频| 日本一区二区三区免费高清在线| 亚洲无线观看国产精品| 99精品在线免费观看| 亚洲国产精品免费观看| 亚洲?V无码成人精品区日韩| 91在线视频免费观看| 亚洲专区在线视频| 好爽又高潮了毛片免费下载| 一级毛片在播放免费| 亚洲人成在线影院| 日韩a在线观看免费观看| 精品多毛少妇人妻AV免费久久| 日韩亚洲AV无码一区二区不卡| 欧洲精品成人免费视频在线观看| 美女黄频视频大全免费的| 亚洲无线码在线一区观看| 日韩视频在线精品视频免费观看| 色五月五月丁香亚洲综合网| 国产亚洲成av片在线观看| 嫖丰满老熟妇AAAA片免费看| 又长又大又粗又硬3p免费视频| 亚洲综合自拍成人| 亚洲国产成人爱av在线播放| 免费人妻无码不卡中文字幕系|