我有一个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);
}
}
}