Java 带参数的forloop中的多线程
我相信我得到的数据是错误的,因为实例变量不是线程安全的 我试图使用多线程的方式,根据列表一次打开(最多)13个线程。我在服务中使用它,需要将参数传递到run方法中,所以我制作了一些实例变量并设置它们。我还希望在进入第一个for循环的下一个迭代之前执行这十三个方法Java 带参数的forloop中的多线程,java,multithreading,Java,Multithreading,我相信我得到的数据是错误的,因为实例变量不是线程安全的 我试图使用多线程的方式,根据列表一次打开(最多)13个线程。我在服务中使用它,需要将参数传递到run方法中,所以我制作了一些实例变量并设置它们。我还希望在进入第一个for循环的下一个迭代之前执行这十三个方法 private EnergyPortalGroup superGroup; private EnergyPortalSubGroups singleSubGroup; private BillingPeriod singlePeriod
private EnergyPortalGroup superGroup;
private EnergyPortalSubGroups singleSubGroup;
private BillingPeriod singlePeriod;
private DateTime[] dateTimeArray;
private void parseGroup(EnergyPortalGroup superGroup) throws InterruptedException{
EnergyPortalSubGroupsCriteria criteria = new EnergyPortalSubGroupsCriteria();
criteria.setGroupId(superGroup.getId());
List<EnergyPortalSubGroups> wholeSubGroupList = subgroupsFactory.readList(criteria);
for (EnergyPortalSubGroups singleSubGroup : wholeSubGroupList){
this.singleSubGroup = singleSubGroup;
this.deleteSubGroupRecordsFromDB(singleSubGroup);
List<BillingPeriod> billingPeriodList = this.getPreviousTwelveBillingPeriods(singleSubGroup, superGroup);
if (billingPeriodList != null && billingPeriodList.size() > 0){
Thread[] threads = new Thread[billingPeriodList.size()];
for (int i = 0; i < billingPeriodList.size(); i++){
this.singlePeriod = billingPeriodList.get(i);
threads[i] = new Thread(this);
threads[i].start();
}
for (Thread thread : threads){
thread.join();
}
}
}
}
私人能源门户集团超群;
私人能源门户子组单子组;
私人计费周期单周期;
私有日期时间[]日期时间数组;
private void parseGroup(EnergyPortalGroup超组)引发InterruptedException{
EnergyPortalSubGroupsCriteria条件=新的EnergyPortalSubGroupsCriteria();
criteria.setGroupId(superGroup.getId());
List-whistubgrouplist=子工厂.readList(标准);
对于(EnergyPortalSubGroups SingleSubgroups:批发分组列表){
this.singleSubGroup=singleSubGroup;
此.deleteSubleRecordsFromDB(singleSubGroup);
List billingPeriodList=this.GetPreviousTwevereBillingPeriods(singleSubGroup,superGroup);
if(billingPeriodList!=null&&billingPeriodList.size()>0){
线程[]线程=新线程[billingPeriodList.size()];
对于(int i=0;i
以下是我的重写运行方法:
@Override
public void run(){
List<GroupSummarization> groupSummarizationsToWriteList = new ArrayList<>();
WidgetDataSummationHolder holder = new WidgetDataSummationHolder();
holder = energyPortalService.getEnergyPortalWidgetsSummedData(singleSubGroup, null, null, singlePeriod);
parseSummationHolder(groupSummarizationsToWriteList, holder, singleSubGroup, dateTimeArray, singlePeriod);
processBatchLists(groupSummarizationsToWriteList, superGroup, singlePeriod);
}
@覆盖
公开募捐{
List GroupSummationStowriteList=新建ArrayList();
WidgetDataSummationHolder=新的WidgetDataSummationHolder();
holder=energyPortalService.GetEnergyPortalWidgetSSUMEDDATA(singleSubGroup,null,null,singlePeriod);
parseSummationHolder(GroupSummationStowriteList,holder,singleSubGroup,dateTimeArray,singlePeriod);
ProcessBatchList(GroupSummationStowriteList、superGroup、singlePeriod);
}
有人能帮我把这根线弄安全吗?我显然是多线程新手,我尝试用构造函数传递这些变量,但我有一些自动连接的服务是空的,我在这一行得到一个空指针
holder=energyPortalService.getEnergyPortalWidgetsSummedData(singleSubGroup,null,null,singlePeriod)代码>根据您提供的代码,energyPortalService有时不能为空,其他时间不能为空。如果在启动新线程时它不为null(this),那么如果要使用新线程(()->{…}),它应该在那里
(既然你说的是自动布线,我就认为osgi和aop以及诸如此类的邪恶行为可能会发生很多恶作剧。)根据你提供的代码,energyPortalService有时不能为空,其他时候不能为空。如果在启动新线程时它不为null(this),那么如果要使用新线程(()->{…}),它应该在那里
(既然你说的是自动布线,我就认为osgi和aop以及诸如此类的邪恶行为可能会发生很多恶作剧。)最后,我选择了ExecutorService和一些建议的新类/服务。下面是一个例子,以防其他人遇到此类问题:
for (final Object x : list){
List<Object> someList = getList();
if (!Collections.isEmpty(someList)){
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<?>> futures = new ArrayList<Future<?>>();
for (final Object n : someList){
futures.add(executorService.submit(new Runnable(){
@Override
public void run(){
someOtherService.process(parameters)
}
}));
}
for (Future<?> f : futures){
try {
f.get();
} catch (InterruptedException | ExecutionException e) {
//do some logging
}
}
}
}
for(最终对象x:列表){
List someList=getList();
如果(!Collections.isEmpty(someList)){
ExecutorService ExecutorService=Executors.newCachedThreadPool();
列表>();
for(最终对象n:someList){
futures.add(executorService.submit(newrunnable()){
@凌驾
公开募捐{
someOtherService.process(参数)
}
}));
}
for(未来f:未来){
试一试{
f、 get();
}捕获(中断异常|执行异常e){
//做些日志记录
}
}
}
}
基本上,这是调用管理线程池的ExecutorService。我调用newCachedThreadPool,以便它根据需要创建新线程,而不是假设如果您看到newFixedThreadPool(n)
,我知道在这种情况下需要多少线程。但是,为了确保线程大小的一致性,在我循环内部循环之后,我循环未来列表(未来是异步计算的未来结果),并调用f.get,如果需要,它将等待计算完成,然后检索其结果
这对我所需要的非常有效。关键部分是,在重写的run函数中,process方法接受您想要的任何参数(注意使用final
),而不是在调用构造函数时试图强制feed run()或担心自动连线服务。这绕过了所有这些
感谢所有让我走上正确道路的人最后,我选择了ExecutorService和一些建议的新类/服务。下面是一个例子,以防其他人遇到此类问题:
for (final Object x : list){
List<Object> someList = getList();
if (!Collections.isEmpty(someList)){
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<?>> futures = new ArrayList<Future<?>>();
for (final Object n : someList){
futures.add(executorService.submit(new Runnable(){
@Override
public void run(){
someOtherService.process(parameters)
}
}));
}
for (Future<?> f : futures){
try {
f.get();
} catch (InterruptedException | ExecutionException e) {
//do some logging
}
}
}
}
for(最终对象x:列表){
List someList=getList();
如果(!Collections.isEmpty(someList)){
ExecutorService ExecutorService=Executors.newCachedThreadPool();
列表>();
for(最终对象n:someList){
futures.add(executorService.submit(newrunnable()){
@凌驾
公开募捐{
someOtherService.process(参数)
}
}));
}
for(未来f:未来){
试一试{
f、 get();
}捕获(中断异常|执行异常e){
//做些日志记录
}
}
}
}
基本上这是电话