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?