A multi-thread interceptor has a Map for storing blacklist,is it useful using a ConcurrentHashMap?

26 Views Asked by At

I want to intercept the request which access the website over 3 times in a second.So i use a Map<String,Long[]> to record the ip-addr and the access time.Evertime i want to put the map , i need to get the map first , so is ConcurrentHashMap useful?

public class BlackListInterceptor {
    private static final Map<String, long[]> ipMillisMap = new ConcurrentHashMap<>();

    private boolean intercept(String remoteAddr) {
        String addrNumber = remoteAddr.replaceAll(":", "");
        return interceptOnce(addrNumber);
    }

    private Boolean interceptOnce(String addrNumber) {
        long currentMillis = System.currentTimeMillis();
        int count = CommonConst.REQUEST_COUNT_PER_SECOND;// 3
        long[] thisArr;
        // get first 
        if ((thisArr = ipMillisMap.get(addrNumber)) == null) {
            long[] millis = new long[count];
            millis[0] = currentMillis;
            //then put the new array.I thought only the put() is synchronized,if a thread alter the data between the get() and the put(),i may get a wrong data.
            ipMillisMap.put(addrNumber, millis);
            return Boolean.FALSE;
        }
        boolean shouldIntercepted;
        for (int i = 1; i < count; i++) {
            if (thisArr[i] == 0) {
                //Here alter the array is not synchronized,so i may get the wrong data .
                thisArr[i] = currentMillis;
                return Boolean.FALSE;
            }
        }
        shouldIntercepted = currentMillis - thisArr[0] >= 1000;
        //also here.
        long[] newArr = new long[thisArr.length];
        System.arraycopy(thisArr, 1, newArr, 0, thisArr.length - 1);         
        newArr[thisArr.length - 1] = currentMillis;
        ipMillisMap.put(addrNumber, newArr);
    return shouldIntercepted;
    }
}

So what should i do ? I think synchronize the interceptOnce method is useful,but do i have another way?

I tried synchronize the whole method and i thought it is useful.But i want to know is there any other way?

0

There are 0 best solutions below