原型bean之间的共享bean线程安全吗?

时间:2018-05-04 07:28:00

标签: java spring dependency-injection

我有一个prototype bean,我在多线程应用程序中使用它。我正在使用ThreadPoolExecutionService来运行prototype的不同实例。

我想收集关于线程正在运行的代码的一些统计信息,其中包括创建多个变量,并在原型运行时递增它们。

我想创建一个singleton bean,并将bean注入prototype,然后调用一个方法来设置统计信息。

一些虚拟代码来说明这一点:虚拟代码归功于mykong,我稍微修改了一下。

public static void main( String[] args )
{

    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

    PrintThread printThread1 = (PrintThread) ctx.getBean("printThread");
    printThread1.setName("Thread 1");

    PrintThread printThread2 = (PrintThread) ctx.getBean("printThread");
    printThread2.setName("Thread 2");

    PrintThread printThread3 = (PrintThread) ctx.getBean("printThread");
    printThread3.setName("Thread 3");

    PrintThread printThread4 = (PrintThread) ctx.getBean("printThread");
    printThread4.setName("Thread 4");

    PrintThread printThread5 = (PrintThread) ctx.getBean("printThread");
    printThread5.setName("Thread 5");

    printThread1.start();
    printThread2.start();
    printThread3.start();
    printThread4.start();
    printThread5.start();

}

printThread,带注入:

@Component
@Scope("prototype")
public class PrintThread extends Thread{

@Inject
private StatGatherer statGatherer;

@Override
public void run() {

    System.out.println(getName() + " is running");

    //is this threadsafe?   
    statGatherer.writeSomeStat(); 

    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(getName() + " is running");
}

}

编辑:threadsafe stats类的示例。代码包含三个映射,可以通过同步方法递增。

@Component("statistics")
public class StatGathererImpl implements StatGatherer {

private ConcurrentHashMap<Character, Integer> mappingType = new ConcurrentHashMap<>();
private ConcurrentHashMap<Character, Integer> mappingGroup = new ConcurrentHashMap<>();
private ConcurrentHashMap<Character, Integer> mappingDirection = new ConcurrentHashMap<>();

@Override
public synchronized void incrementMappingType(char mapType) {
    if(mappingType.keySet().contains(mapType)){
        mappingType.replace(mapType, mappingType.get(mapType), mappingType.get(mapType)+1);
    }else{
        mappingType.put(mapType, 1);
    }
}

@Override
public synchronized void incrementMappingGroup(char mapGroup) {
    if(mappingGroup.keySet().contains(mapGroup)){
        mappingGroup.replace(mapGroup, mappingGroup.get(mapGroup), mappingGroup.get(mapGroup)+1);
    }else{
        mappingGroup.put(mapGroup, 1);
    }
}

@Override
public synchronized void incrementMappingDirection(char mapDirection) {
    if(mappingDirection.keySet().contains(mapDirection)){
        mappingDirection.replace(mapDirection, mappingDirection.get(mapDirection), mappingDirection.get(mapDirection)+1);
    }else{
        mappingDirection.put(mapDirection, 1);
    }
}
}

0 个答案:

没有答案