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;
}