并行任务中的迭代器值问题
Issue with iterator value in parallel task
我有一个 for 循环作为可调用 class 的一部分,它由线程池执行器并行执行多次。可调用 class 的其余部分似乎正常运行。我认为这很重要。只有迭代器导致了问题。所以这是 411:循环运行,它在离散列表中搜索警报。当它找到一个时(每当我绊倒其中任何一个时它都会这样做)它应该创建一个警报对象并为其提供其在列表中的位置的 ID。这就是迭代器的用途。
直到我让这个任务并行执行,迭代器(int i)每次都返回它在数组中的位置。现在它只有 returns 值 0 尽管正确迭代数组。
这是可调用的相关代码。迭代器不是线程安全的还是什么?我很困惑。
//Create a list to store discretes
boolean[] boolist = new boolean[1024];
//Read values from the site and assign them to the boolean array
mbc.readInputDiscretes(1, 0, boolist);
for (int i = 0; i < boolist.length; i++) {
//Checks to see if the alarm is alarmed. Do not be alarmed if the alarm is alarmed.
if(boolist[i]){
//For each value of true we create a new alarm tag, set the alarm to active within the system, record its site ID and its Tag ID.
TagInfo alarmtag = new TagInfo(true, InfoBox.getSiteID(), i);
//THE ITERATOR ABOVE ONLY RETURNS 0, HOWEVER IT ITERATES THROUGH THE LIST PROPERLY. SO ALL TAGS ARE NOTICED BUT RETURN WITH AN ID OF 0. AHHHHHH.
//Add the tag to the list to return.
alarmtags.add(alarmtag);
}
}
编辑:
应要求,这里是 TagInfo 的相关部分 class:
public class TagInfo {
private int siteID; //ID # of the site this tag belongs to
private int tagID; //ID # of the tag itself
private int tagOffset; //Integer 1-1024 related to the tags read position at its given site
private int tagType; //The type of tag (not yet implemented, just thought it would be useful eventually)
private int tagEscDly; //The amount of time to wait before we raise the priority level of an alarm referencing this specific tag
private Timestamp lastPolled; //The last time this site was checked
private boolean alarmstatus; //The alarm status of this specific tag, e.g. in alarm or not in alarm
//Default empty constructor for TagInfo object
public TagInfo(){}
//Overloaded constructor for faster initialization of objects and fewer method calls
public TagInfo(boolean alarmstatus, int siteID, int tagID){
this.alarmstatus = alarmstatus;
this.siteID = siteID;
this.tagID = tagID;
}
这是调用可调用对象的代码:
//Invoke run method on each site simultaneously, store results in a list
List<Future<List<TagInfo>>> futures=threadmaker.invokeAll(active_sites.stream().map(site -> new TAG_SCANNER(site, loggr)).collect(Collectors.toList()));
已解决:问题在于使用了不正确的变量。
我有一个 for 循环作为可调用 class 的一部分,它由线程池执行器并行执行多次。可调用 class 的其余部分似乎正常运行。我认为这很重要。只有迭代器导致了问题。所以这是 411:循环运行,它在离散列表中搜索警报。当它找到一个时(每当我绊倒其中任何一个时它都会这样做)它应该创建一个警报对象并为其提供其在列表中的位置的 ID。这就是迭代器的用途。
直到我让这个任务并行执行,迭代器(int i)每次都返回它在数组中的位置。现在它只有 returns 值 0 尽管正确迭代数组。
这是可调用的相关代码。迭代器不是线程安全的还是什么?我很困惑。
//Create a list to store discretes
boolean[] boolist = new boolean[1024];
//Read values from the site and assign them to the boolean array
mbc.readInputDiscretes(1, 0, boolist);
for (int i = 0; i < boolist.length; i++) {
//Checks to see if the alarm is alarmed. Do not be alarmed if the alarm is alarmed.
if(boolist[i]){
//For each value of true we create a new alarm tag, set the alarm to active within the system, record its site ID and its Tag ID.
TagInfo alarmtag = new TagInfo(true, InfoBox.getSiteID(), i);
//THE ITERATOR ABOVE ONLY RETURNS 0, HOWEVER IT ITERATES THROUGH THE LIST PROPERLY. SO ALL TAGS ARE NOTICED BUT RETURN WITH AN ID OF 0. AHHHHHH.
//Add the tag to the list to return.
alarmtags.add(alarmtag);
}
}
编辑:
应要求,这里是 TagInfo 的相关部分 class:
public class TagInfo {
private int siteID; //ID # of the site this tag belongs to
private int tagID; //ID # of the tag itself
private int tagOffset; //Integer 1-1024 related to the tags read position at its given site
private int tagType; //The type of tag (not yet implemented, just thought it would be useful eventually)
private int tagEscDly; //The amount of time to wait before we raise the priority level of an alarm referencing this specific tag
private Timestamp lastPolled; //The last time this site was checked
private boolean alarmstatus; //The alarm status of this specific tag, e.g. in alarm or not in alarm
//Default empty constructor for TagInfo object
public TagInfo(){}
//Overloaded constructor for faster initialization of objects and fewer method calls
public TagInfo(boolean alarmstatus, int siteID, int tagID){
this.alarmstatus = alarmstatus;
this.siteID = siteID;
this.tagID = tagID;
}
这是调用可调用对象的代码:
//Invoke run method on each site simultaneously, store results in a list
List<Future<List<TagInfo>>> futures=threadmaker.invokeAll(active_sites.stream().map(site -> new TAG_SCANNER(site, loggr)).collect(Collectors.toList()));
已解决:问题在于使用了不正确的变量。