HashMap&&Redis Concurrent Problem

來源:互聯網
上載者:User

標籤:

1.前幾天修改一個bug的時候發現一個Java資料結果並發的問題。大致過程如下:
其中Bean的資料結果如下,其中包含一個Map,主要是為了記錄使用者的使用次數。

public class Bean {    private Map<String,String> map = new HashMap<String,String>();    private String userId;    private int count = 0;    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + count;        result = prime * result + ((map == null) ? 0 : map.hashCode());        result = prime * result + ((userId == null) ? 0 : userId.hashCode());        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Bean other = (Bean) obj;        if (count != other.count)            return false;        if (map == null) {            if (other.map != null)                return false;        } else if (!map.equals(other.map))            return false;        if (userId == null) {            if (other.userId != null)                return false;        } else if (!userId.equals(other.userId))            return false;        return true;    }    @Override    public String toString() {        return "Bean [map=" + map + ", userId=" + userId + ", count=" + count + "]";    }    public Map<String, String> getMap() {        return map;    }    public void setMap(Map<String, String> map) {        this.map = map;    }    public String getUserId() {        return userId;    }    public void setUserId(String userId) {        this.userId = userId;    }    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub    }}

Runnable:

public class TaskRunnable implements Runnable{    private int operationNumber;    public TaskRunnable(int a){        this.operationNumber = a;    }    @Override    public void run() {        Action action = new Action();        Bean bean = action.getAndUpdateBeanFromCache();        System.out.println("threadId is id = " + Thread.currentThread().getId());        if(bean==null){            bean = new Bean();            bean.setUserId("12344");            bean.setCount(11);        }        Map<String,String> map = bean.getMap();        map.put(operationNumber+"",operationNumber+"");        System.out.println("map key = " + operationNumber + " ," + " value = " + operationNumber);        RedisUtil.setCache(RedisConstant.testKey, new Gson().toJson(bean));    }}

Action:

public class Action {    public Bean getAndUpdateBeanFromCache(){        Bean bean = new Bean();        String key = RedisConstant.testKey;        String value = RedisUtil.getCache(key);        Type type = new TypeToken<Bean>(){}.getType();        bean = new Gson().fromJson(value,type);        return bean;    }}

MainClass:

public class MainClass {    public static void main(String[] args) throws InterruptedException {        for(int i = 0;i<100;i++){            Thread t = new Thread(new TaskRunnable(i)); //啟動一百個線程測試            t.start();        }    }}

出現的問題,啟動的一百個線程中並不是沒有count都被記錄下來,主要原因是因為HashMap這種資料結構在並發的時候存在一定的問題,但是如何解決這個問題,最後採用了Redis Hash Map的資料結構記錄了使用者的使用,經測試不會出現並發問題。主要原因是Redis是個單線程啟動並執行程式,其中HashMap並不會出現這個並發的問題。

2.曾憲傑 大型網站系統與Java中介軟體實踐
在這個本書中舉出一個例子,跟這個很相似,如下:

public class TestClass {    private HashMap<String,Integer> map = new HashMap<String,Integer>();    public synchronized void add(String key){        Integer value = map.get(key);        if(value==null){            map.put(key, 1);        }else{            map.put(key, value+1);        }    }}

這個方法雖然能夠正確的計數,但是在高並發的時候,卻十分的影響效能,效率不高。將Map換成ConcurrentHashMap這個結構,代碼如下:

public class TestClass {    private ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String,Integer>();    public void add(String key){        Integer value = map.get(key);        if(value==null){            map.put(key, 1);        }else{            map.put(key, value+1);        }    }}

這樣的寫法顯然會造成高並發的線程的問題。
—-路漫漫其修遠兮,吾將上下而求索!

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

HashMap&&Redis Concurrent Problem

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.