Java:我的方法是线程安全的吗?

Java:我的方法是线程安全的吗?,java,multithreading,Java,Multithreading,在类CACallHandler中,有一个由我创建的方法,即checkCallAllowed。我把一切都当作ConcurrentHashMap和AtomicInteger 请忽略checkCallAllowed的逻辑,但我想知道,如果多个线程将同时访问同一对象上的此方法,那么它将是安全的 我不想同步整个方法,因为会出现性能问题 请求你的帮助 我已经用30个线程执行了这个方法,其中有同步的方法,也有没有同步的方法,两者都给出了相同的结果。所以我想知道,如果有200个线程,那么它是否安全 public

在类
CACallHandler
中,有一个由我创建的方法,即
checkCallAllowed
。我把一切都当作ConcurrentHashMap和AtomicInteger

请忽略
checkCallAllowed
的逻辑,但我想知道,如果多个线程将同时访问同一对象上的此方法,那么它将是安全的

我不想
同步整个方法,因为会出现性能问题

请求你的帮助

我已经用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 cleared-111@@!!---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;
}
public类CACallHandler{
公共节流阀节流阀节流阀;
Map criteriaMap=新建HashMap();
List listenerList=新建链接列表();
Map intervalMap=新的ConcurrentHashMap();
Map oddMap=新的ConcurrentHashMap();
Map evenMap=新的ConcurrentHashMap();
Map alarmsRaised=新的ConcurrentHashMap();
公共映射getCurrentMap(){
字符串abc=newsimpledateformat(“ss”).format(newdate());
if(Integer.parseInt(abc)%2==0){
//偶数图
返回均匀图;
}否则{
//奇数图
返回地图;
}
}
公共字符串getCriteria(字符串调用编号、字符串原始编号1、字符串原始编号2){
字符串标准名称=”;
对于(Map.Entry:criteriaMap.entrySet())
{
TCACriteria=entry.getValue();
if(callingNo.equals(criteria.callingNo)| Origin1.equals(criteria.sipOrigin)| Origin2.equals(criteria.inapOrigin)){
criteriaName=entry.getKey();
返回标准名称;
}
}
返回标准名称;
}
允许公共布尔checkcall(字符串调用、字符串Origin1、字符串Origin2){
布尔返回标志=false;
String currentCriteria=getCriteria(调用,Origin1,Origin2);//测试
如果(!currentCriteria.isEmpty()){
字符串abc=newsimpledateformat(“ss”).format(newdate());
if(Integer.parseInt(abc)%2==0){
//基于秒数获取奇数贴图
if(oddMap.get(currentCriteria.get()!=0){
for(int i=0;i=throttleCalalert.getLwm()){
intervalMap.get(currentCriteria)[i].set(oddMap.get(currentCriteria.get());
}否则{
if(alarmsRaised.get(currentCriteria)!=null&&oddMap.get(currentCriteria.get()>>.currentCriteria”+currentCriteria);
listenerList.get(0).alarmCleared(currentCriteria,ThrottleAlarmType.MAJOR);
alarmsRaised.put(currentCriteria,alarmsRaised.get(currentCriteria)).set(2,ThrottleAlarmType.NONE);
}
}
for(int j=0;j>>.currentCriteria”+currentCriteria);
//开始
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);
get(0).AlarmRised(currentCriteria,ThrottleAlarmType.MAJOR);
}
}
//结束
}
if(alarmsRaised.get(currentCriteria)!=null&&oddMap.get(currentCriteria.get()>>.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(currentCriter
public class CACallHandler {

    //Only one SimpleDateFormat instance is enought to format all dates
    private SimpleDateFormat sdfSS = new SimpleDateFormat("ss");

    public ThrottleCallAlert throttleCallAlert;

    List<TCAListener> listenerList =  new LinkedList< TCAListener>();
    Map<String, TCACriteria> criteriaMap = new HashMap<String, TCACriteria>();
    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>>();
    static String[] testeValues = {"callingNo", "sipOrigin", "inapOrigin", "A", "B", "C"};


    {//Populates values to test

        throttleCallAlert = new ThrottleCallAlert();

        criteriaMap.put("callingNo", new TCACriteria());
        criteriaMap.put("sipOrigin", new TCACriteria());
        criteriaMap.put("inapOrigin", new TCACriteria());

        evenMap.put("callingNo", new AtomicInteger(1));
        evenMap.put("sipOrigin", new AtomicInteger(2));
        evenMap.put("inapOrigin", new AtomicInteger(3));

        oddMap.put("callingNo", new AtomicInteger(1));
        oddMap.put("sipOrigin", new AtomicInteger(2));
        oddMap.put("inapOrigin", new AtomicInteger(3));

        intervalMap.put("callingNo", new AtomicInteger[] { new AtomicInteger(1), new AtomicInteger(2), new AtomicInteger(3) });
        intervalMap.put("sipOrigin", new AtomicInteger[] { new AtomicInteger(1), new AtomicInteger(2), new AtomicInteger(3) });
        intervalMap.put("inapOrigin", new AtomicInteger[] { new AtomicInteger(1), new AtomicInteger(2), new AtomicInteger(3) });
    }


    public static void main(String[] args) throws InterruptedException {
        CACallHandler handler = new CACallHandler();
        int threads = 10000;
        ExecutorService taskExecutor = Executors.newFixedThreadPool( threads );
        //Thread.sleep(12000);
        Date startTime = new Date();
        for( int i = 0 ; i < threads; i++ ) {
            int i1 = ThreadLocalRandom.current().nextInt(0, 5 + 1);
            int i2 = ThreadLocalRandom.current().nextInt(0, 5 + 1);
            int i3 = ThreadLocalRandom.current().nextInt(0, 5 + 1);
            taskExecutor.execute( new Thread(){ public void run() {handler.checkCallAllowed(testeValues[i1], testeValues[i2], testeValues[i3]);} }  );
        }
        taskExecutor.shutdown();
        taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        Date finishTime = new Date();
        System.out.println( "Execution time in ms: " + (finishTime.getTime() - startTime.getTime()) );

    }



    /**
     * Return the odd or even map based on current time
     * @return Map 
     */
    public Map<String, AtomicInteger> getCurrentMap(){
        switch( getCurrentMapType() ) {
            case EVEN: return evenMap;
            case ODD: return oddMap;
            default: return null;
        }
    }

    /**
     * Check if criteriaMap has the [callingNo | Origin1 | Origin2] passed 
     * @param callingNo - 
     * @param Origin1
     * @param Origin2
     * @return String - the criteriaMap key equals to parameter or empty string
     */
    public String getCriteria(String callingNo, String Origin1, String Origin2){
        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))
                return entry.getKey();
        }
        return null;
    }

    /**
     * get odd map type based on seconds
     * @return MapType
     */
    private MapType getCurrentMapType() {
        return MapType.EVEN;//No odd implementation
        /*if(Integer.parseInt( sdfSS.format(new Date()) ) % 2 == 0){
            return MapType.EVEN;
        }else{
            return MapType.ODD;
        }*/     
    }

    /**
     * Get the currente criteria based on parameters then process it
     * @param calling
     * @param Origin1
     * @param Origin2
     * @return
     */
    public boolean checkCallAllowed(String calling, String Origin1, String Origin2){
        String currentCriteria = getCriteria(calling, Origin1, Origin2);
        if( currentCriteria != null ){
            switch( getCurrentMapType() ) {
                case EVEN: return proccessEvenMapType(currentCriteria);
                case ODD: return proccessOddMapType(currentCriteria);
                default: return false; //TODO check it
            }
        }
        return false;
    }

    /**
     * Process currentcriteria based on even Map
     * @param currentCriteria
     * @return boolean - always false??
     */
    private synchronized boolean proccessEvenMapType( String currentCriteria ) {
        boolean returnFlag = false; //TODO this variable never receivs true..??
        //Only one call to map, reduce the time on searching and processing
        Integer currentCriteriaValue = oddMap.get(currentCriteria).get();
            if(currentCriteriaValue != 0 ){
                //Only one call to map, reduce the time on searching and processing 
                AtomicInteger[] intervalArray = intervalMap.get(currentCriteria);
                for(int intervalIndex=0; intervalIndex < intervalArray.length; intervalIndex++){
                    AtomicInteger currentInterval = intervalArray[intervalIndex];
                    System.out.println("aaaaa :"+ currentInterval.get());
                    if(currentInterval.get() == -1 ){
                        if(currentCriteriaValue >= throttleCallAlert.getLwm()){
                            currentInterval.set(currentCriteriaValue);
                        }else{
                            List<ThrottleAlarmType> alarmTypeList = alarmsRaised.get(currentCriteria) ; 
                            if(alarmTypeList != null && currentCriteriaValue < throttleCallAlert.getLwm()){
                                if(alarmTypeList.contains(ThrottleAlarmType.MAJOR)){
                                    System.out.println("ALARM cleared-111@@!!---MAJOR-->>>. currentCriteria "+currentCriteria);
                                    listenerList.get(0).alarmCleared(currentCriteria, ThrottleAlarmType.MAJOR);
                                    alarmsRaised.put(currentCriteria, alarmTypeList).set(2, ThrottleAlarmType.NONE);
                                }
                            }
                            for(int j=0; j < intervalArray.length; j++){
                                intervalArray[j] = new AtomicInteger(-1);
                            }
                        }
                        break;
                    }

                    if(intervalIndex == intervalArray.length - 1){
                        int majorAlarm = 0; 
                        boolean raiseAlarmRequired = true;
                        System.out.println("array not -1 111");
                        for(int j=0; j < intervalArray.length; j++){
                            if(intervalArray[j].get() < throttleCallAlert.getLwm() ){
                                raiseAlarmRequired = false;
                            }
                            intervalArray[j] = new AtomicInteger(-1);
                        }

                        if(raiseAlarmRequired){
                            System.out.println("ALARM RAISED--11---->>>. currentCriteria " + currentCriteria);
                            //start
                            if(majorAlarm == intervalArray.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 && currentCriteriaValue < 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);
                            }
                        }
                        intervalArray[0].set(currentCriteriaValue); 
                    }

                }
                oddMap.get(currentCriteria).set(0);
            }
        // even map 
        evenMap.get(currentCriteria).incrementAndGet();
        return returnFlag;
    }

    private boolean proccessOddMapType( String currentCriteria ) {
        System.out.println("proccessOddMapType Not implemented yet!!");
        return false;
    }

}

enum MapType{
    ODD, EVEN;
}