在类CACallHandler
有一个由我创建的方法,即checkCallAllowed
。我已将所有内容都用作ConcurrentHashMap和AtomicInteger。Java:我的方法线程安全吗?
请忽略checkCallAllowed
的逻辑,但我想知道如果多个线程将同时访问同一个对象上的此方法,那么它会安全。
我不想synchronize
整个方法,因为会有一个表演。
请求您的帮助。
我已经执行此方法与30个线程有和没有方法同步,都给出相同的结果。所以想要了解是否会有200个线程,那么它会安全或不安全。
public class CACallHandler {
public ThrottleCallAlert throttleCallAlert ;
Map<String, TCACriteria> criteriaMap = new HashMap<String, TCACriteria>();
List<TCAListener> listenerList = new LinkedList< TCAListener>();
Map<String, AtomicInteger[]> intervalMap = new ConcurrentHashMap<String, AtomicInteger[]>();
Map<String, AtomicInteger> oddMap = new ConcurrentHashMap<String, AtomicInteger>();
Map<String, AtomicInteger> evenMap = new ConcurrentHashMap<String, AtomicInteger>();
Map<String, List<ThrottleAlarmType> > alarmsRaised = new ConcurrentHashMap<String, List<ThrottleAlarmType>>();
public Map<String, AtomicInteger> getCurrentMap(){
String abc = new SimpleDateFormat("ss").format(new Date());
if(Integer.parseInt(abc) % 2 == 0){
// even map
return evenMap;
}else{
// odd map
return oddMap;
}
}
public String getCriteria(String callingNo, String Origin1, String Origin2){
String criteriaName = "";
for (Map.Entry<String, TCACriteria> entry : criteriaMap.entrySet())
{
TCACriteria criteria = entry.getValue();
if(callingNo.equals(criteria.callingNo) || Origin1.equals(criteria.sipOrigin) || Origin2.equals(criteria.inapOrigin)){
criteriaName = entry.getKey();
return criteriaName;
}
}
return criteriaName;
}
public boolean checkCallAllowed(String calling, String Origin1, String Origin2){
boolean returnFlag = false;
String currentCriteria = getCriteria(calling, Origin1, Origin2); // test
if(!currentCriteria.isEmpty()){
String abc = new SimpleDateFormat("ss").format(new Date());
if(Integer.parseInt(abc) % 2 == 0){
//taking odd map based on seconds
if(oddMap.get(currentCriteria).get() != 0){
for(int i=0; i < intervalMap.get(currentCriteria).length; i++){
System.out.println("aaaaa :"+ intervalMap.get(currentCriteria)[i].get());
if(intervalMap.get(currentCriteria)[i].get() == -1){
if(oddMap.get(currentCriteria).get() >= throttleCallAlert.getLwm()){
intervalMap.get(currentCriteria)[i].set(oddMap.get(currentCriteria).get());
}else{
if(alarmsRaised.get(currentCriteria) != null && oddMap.get(currentCriteria).get() < throttleCallAlert.getLwm()){
if(alarmsRaised.get(currentCriteria).contains(ThrottleAlarmType.MAJOR)){
System.out.println("ALARM [email protected]@!!---MAJOR-->>>. currentCriteria "+currentCriteria);
listenerList.get(0).alarmCleared(currentCriteria, ThrottleAlarmType.MAJOR);
alarmsRaised.put(currentCriteria, alarmsRaised.get(currentCriteria)).set(2, ThrottleAlarmType.NONE);
}
}
for(int j=0; j < intervalMap.get(currentCriteria).length; j++){
intervalMap.get(currentCriteria)[j] = new AtomicInteger(-1);
}
}
break;
}
if(i == intervalMap.get(currentCriteria).length - 1){
int majorAlarm = 0;
boolean raiseAlarmRequired = true;
System.out.println("array not -1 111");
for(int j=0; j < intervalMap.get(currentCriteria).length; j++){
if(intervalMap.get(currentCriteria)[j].get() < throttleCallAlert.getLwm()){
raiseAlarmRequired = false;
}
intervalMap.get(currentCriteria)[j] = new AtomicInteger(-1);
}
if(raiseAlarmRequired){
System.out.println("ALARM RAISED--11---->>>. currentCriteria " + currentCriteria);
//start
if(majorAlarm == intervalMap.get(currentCriteria).length){ // major
if((alarmsRaised.get(currentCriteria) != null && ! alarmsRaised.get(currentCriteria).contains(ThrottleAlarmType.MAJOR))){
returnFlag = false;
alarmsRaised.put(currentCriteria, alarmsRaised.get(currentCriteria)).set(2, ThrottleAlarmType.MAJOR);
listenerList.get(0).alarmRaised(currentCriteria, ThrottleAlarmType.MAJOR);
}
}
//end
}
if(alarmsRaised.get(currentCriteria) != null && oddMap.get(currentCriteria).get() < throttleCallAlert.getLwm()){
if(alarmsRaised.get(currentCriteria).contains(ThrottleAlarmType.WARNING)){
System.out.println("ALARM cleared-111----->>>. currentCriteria "+currentCriteria);
listenerList.get(0).alarmCleared(currentCriteria, ThrottleAlarmType.WARNING);
alarmsRaised.put(currentCriteria, alarmsRaised.get(currentCriteria)).set(0, ThrottleAlarmType.NONE);
}
}
intervalMap.get(currentCriteria)[0].set(oddMap.get(currentCriteria).get());
}
}
oddMap.get(currentCriteria).set(0);
}
// even map
evenMap.get(currentCriteria).incrementAndGet();
}else{
// takeing even map same as odd map mentioned above
}
}
return returnFlag;
}
}
那些地图的内容会在程序执行过程中发生变化吗?如果他们这样做,我认为你可能会在方法中产生不一致的读取,因为你的条件逻辑在读取之间没有同步。 –
好吧,看起来这个方法本身至少在变异警报图。它看起来没有线程安全。我的意思是,来自CHM的数据访问是线程安全的,但这些调用之间的逻辑没有同步。 –
@米克助记符:方法本身就是改变报警图,奇图,偶图,区间图的值。这些是并发哈希映射,值是原子整数。它不是线程安全的吗?如果不是,我该怎么做才能保证线程安全 – VJS