如何修复Java中的可调用重叠?

如何修复Java中的可调用重叠?,java,concurrency,callable,invokeall,Java,Concurrency,Callable,Invokeall,我不确定标题是否详细/正确,但我不知道如何在标题中描述它,因此我将尽我最大的努力在这里描述它 我一直在尝试在Java中使用callable来实现并发性,但结果并不正确,似乎线程在运行时相互重叠了……下面是用于此目的的调用函数 @Override public String call() { String result = "yay"; long startTime = System.currentTimeMillis(); long endTime = startTime

我不确定标题是否详细/正确,但我不知道如何在标题中描述它,因此我将尽我最大的努力在这里描述它

我一直在尝试在Java中使用callable来实现并发性,但结果并不正确,似乎线程在运行时相互重叠了……下面是用于此目的的调用函数

@Override
public String call() {
    String result = "yay";
    long startTime = System.currentTimeMillis();
    long endTime = startTime + timeOutMiliseconds * 1000;
    while (System.currentTimeMillis() < endTime) {
        int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
        System.out.println(" current - " + Arrays.toString(currentMapping) + " - " +  ID);
        result = Arrays.toString(currentMapping);
    }
    return result;
}
这是主要的

public static void main(String[] args) throws InterruptedException, ExecutionException {
    Callable<String> Array = new MarkovTest(1, 0, 1);
    Callable<String> Array2 = new MarkovTest(2, 2, 3);
    Callable<String> Array3 = new MarkovTest(3, 4, 5);

    List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);

    List<Future<String>> future = executor.invokeAll(taskList);
    for(Future<String> result : future)
    {
        System.out.println(result.get());
    }
}
第1行正确,ID 1应打印第一个索引在0到1范围内的数组。 但是ID3和ID2不应该在第一个索引中有0或1…这并不是一直发生的,而是会在数千个控制台输出中出现

知道为什么会这样吗?因为这个,我真的很紧张

编辑:添加了
generatetpumpappingwithrange

private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
    final Logger log = Logger.getLogger(MarkovTest.class);

    int maximumNoOfCoreIndex = 6;
    int minimumNoOfCoreIndex = 0;
    int firstIndex = 0;
    int[] result = iap;
    log.debug("OLD MAPPING = " + Arrays.toString(result));
    // generate random
    Random randomNum = new Random();
    // generate number from 0 -> 13 (because last number will always be 6)
    int randomIndex = randomNum.nextInt(iap.length - 1);
    // last one will always be 6 so dont need to include that
    int minusOrPlus = 0;
    minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
    Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
    PuType thisTaskPuType = domains.get(thisTask);
    int[] newIndexValueRange = this.intervals.get(thisTaskPuType);

    minimumNoOfCoreIndex = newIndexValueRange[0];
    maximumNoOfCoreIndex = newIndexValueRange[1];
    int newIndexValue = result[randomIndex] + minusOrPlus;
    // Split 0-1, 2-3, 4-5 for 3 markov chain.
    if (randomIndex == firstIndex) {
        if (newIndexValue > stopRange) {
            newIndexValue = startRange;
        } else if (newIndexValue < startRange) {
            newIndexValue = stopRange;
        }
    } else {
        if (newIndexValue > maximumNoOfCoreIndex) {
            newIndexValue = minimumNoOfCoreIndex;
        } else if (newIndexValue < minimumNoOfCoreIndex) {
            newIndexValue = maximumNoOfCoreIndex;
        }
    }
    // if the new index value generated from line above surpass our maximum no of
    // core, then it will return to number 0
    // This may resolve to infinite loop if THE SAME randomIndex appear again and
    // again and again and again, which hopefully wont be a thing for this
    // implementation

    result[randomIndex] = newIndexValue;
    log.debug("NEW MAPPING = " + Arrays.toString(result));
    log.debug(" location =" + randomIndex + " value =" + newIndexValue);
    return result;
}

}

看看我在代码摘录中的内联注释:

public static void main(String[] args) throws InterruptedException, ExecutionException {
    org.apache.log4j.BasicConfigurator.configure();
    Logger.getRootLogger().setLevel(Level.INFO);
    long startTime = System.currentTimeMillis();   

    //-----> You have created an instance of ia
    int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
    final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));  

//-----> You have passed the _same_ instance to all of the constructor calls
    Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
    Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
    Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);  
    ...    

 //---->lets move a bit down to the method that's called within the Callable  

private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {  
   ...    
  int firstIndex = 0;
   ...  
   int randomIndex = random.nextInt(iap.length - 1);  
   ...  
 //---> this part should make sure what you are stating, that "ID 1 should print array with first index in range 0 to 1." and this is correct
   if (randomIndex == firstIndex) {

        if (newIndexValue > stopRange) {
            newIndexValue = startRange;
        } else if (newIndexValue < startRange) {
            newIndexValue = stopRange;
        }

    }  else {
        if (newIndexValue > maximumNoOfCoreIndex) {
            newIndexValue = minimumNoOfCoreIndex;
        } else if (newIndexValue < minimumNoOfCoreIndex) {
            newIndexValue = maximumNoOfCoreIndex;
        }
    }
       ...
只是别忘了更改所有参考,尤其是在:

@Override
public String call() {
...
while (System.currentTimeMillis() < endTime) {  
//----> ia to ia_copy 
        int[] currentMapping = generateTpuMappingWithRange(ia_copy , startRange, stopRange);  
...
@覆盖
公共字符串调用(){
...
而(System.currentTimeMillis()ia至ia副本
int[]currentMapping=generatetpumpappingwithrange(ia_copy,startRange,stopRange);
...

请阅读“如何创建一个”链接,然后使用该链接改进您的问题(不要通过评论添加更多信息)。否则,我们无法回答您的问题并帮助您。我认为这确实关系到您的MarkovTest类的具体功能。例如:它是否具有静态字段?!您是否也可以发布
generateTpuMappingWithRange
?如前所述…类似init()的内容方法可能很重要。@BurakSerdar我试图简化代码,因为其中涉及更多内容…但我刚刚添加了generate TpumappingwithRange.GhostCatsaySrestatemonica类中没有任何静态字段…我是否应该将整个类发布到这里?…重申GhostCatsaySrestatemonica,查看所有这些代码需要要投入大量的时间去了解正在发生的事情,这是不太可能发生的。如果你想得到一个答案的可能性很高,最好把问题尽可能地孤立开来,最好是把一个简单的例子,不需要预先的知识。如果有帮助的话,请考虑接受我的回答和/或投票。s、 我在发帖后不久就修复了它,我的电子邮件收件箱没有通知stackoverflow,很抱歉我的投票/接受晚了,没有意识到有人在这上面发帖。我道歉。
public class MarkovTest implements Callable<String> {
static ExecutorService executor = Executors.newFixedThreadPool(3);

int startRange;
int stopRange;
long timeOutMiliseconds = 1000;
long maxIteration;
Amalthea model;
int[] ia;
int ID;
private final int nbCPUs;
private final int nbPUs;
private final HashMap<Task, PuType> domains = new HashMap<Task, PuType>();
private final HashMap<PuType, int[]> intervals = new HashMap<PuType, int[]>();   

public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
    this.model = model;
    this.ia = ia;
    this.nbCPUs = CommonUtils.getNumberofCPUs(model);
    // this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
    this.nbPUs = CommonUtils.getNumberofPUs(model);
    this.ID = ID;
    this.startRange = startRange;
    this.stopRange = stopRange;
    init();
}

public static void main(String[] args) throws InterruptedException, ExecutionException {
    org.apache.log4j.BasicConfigurator.configure();
    Logger.getRootLogger().setLevel(Level.INFO);
    long startTime = System.currentTimeMillis();
    int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
    final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));

    Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
    Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
    Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);

    List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);

    List<Future<String>> future = executor.invokeAll(taskList);
    for(Future<String> result : future)
    {
        System.out.println(result.get());
    }
    long endTime = System.currentTimeMillis();
    long elapsedTime = endTime - startTime;
    System.out.println(" elapsed Time = " + elapsedTime);
    System.out.println("Done");
}

@Override
public String call() {
    String result = "yay";
    long startTime = System.currentTimeMillis();
    long endTime = startTime + timeOutMiliseconds * 1000;
    while (System.currentTimeMillis() < endTime) {
        int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
        System.out.println(" current - " + Arrays.toString(currentMapping) + " - " +  ID);
        result = Arrays.toString(currentMapping);
    }
    return result;
}

private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
    final Logger log = Logger.getLogger(MarkovTest.class);

    int maximumNoOfCoreIndex = 6;
    int minimumNoOfCoreIndex = 0;
    int firstIndex = 0;
    int[] result = iap;
    log.debug("OLD MAPPING = " + Arrays.toString(result));
    // generate random
    Random randomNum = new Random();
    // generate number from 0 -> 13 (because last number will always be 6)
    int randomIndex = randomNum.nextInt(iap.length - 1);
    // last one will always be 6 so dont need to include that
    int minusOrPlus = 0;
    minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
    Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
    PuType thisTaskPuType = domains.get(thisTask);
    int[] newIndexValueRange = this.intervals.get(thisTaskPuType);

    minimumNoOfCoreIndex = newIndexValueRange[0];
    maximumNoOfCoreIndex = newIndexValueRange[1];
    int newIndexValue = result[randomIndex] + minusOrPlus;
    // Split 0-4, 5-10, 11-13 for 3 markov chain.
    if (randomIndex == firstIndex) {
        if (newIndexValue > stopRange) {
            newIndexValue = startRange;
        } else if (newIndexValue < startRange) {
            newIndexValue = stopRange;
        }
    } else {
        if (newIndexValue > maximumNoOfCoreIndex) {
            newIndexValue = minimumNoOfCoreIndex;
        } else if (newIndexValue < minimumNoOfCoreIndex) {
            newIndexValue = maximumNoOfCoreIndex;
        }
    }
    // if the new index value generated from line above surpass our maximum no of
    // core, then it will return to number 0
    // This may resolve to infinite loop if THE SAME randomIndex appear again and
    // again and again and again, which hopefully wont be a thing for this
    // implementation

    result[randomIndex] = newIndexValue;
    log.debug("NEW MAPPING = " + Arrays.toString(result));
    log.debug(" location =" + randomIndex + " value =" + newIndexValue);
    return result;
}

private void init() {
    final Logger log = Logger.getLogger(CallableForMarkov.class);
    for (final Task t : this.model.getSwModel().getTasks()) {
        boolean cpu = false;
        boolean gpu = false;
        boolean defaultVal = false;
        for (final CallGraphItem geb : t.getCallGraph().getItems()) {
            if (geb instanceof Group) {
                final Group cs = (Group) geb;
                for (final CallGraphItem csi : cs.getItems()) {
                    if (csi instanceof RunnableCall) {
                        final RunnableCall trc = (RunnableCall) csi;
                        for (final CallGraphItem ri : trc.getRunnable().getRunnableItems()) {
                            if (ri instanceof Ticks) {
                                final Ticks ticks = (Ticks) ri;
                                if (null != ticks.getDefault() && ticks.getDefault().getAverage() > 0) {
                                    defaultVal = true;
                                }
                                for (final Entry<ProcessingUnitDefinition, IDiscreteValueDeviation> e : ticks
                                        .getExtended().entrySet()) {
                                    if (!gpu && e.getKey().getPuType().equals(PuType.GPU)) {
                                        gpu = true;
                                    } else if (!cpu && e.getKey().getPuType().equals(PuType.CPU)) {
                                        cpu = true;
                                    }
                                }
                            }
                        }
                        // TODO check if there are runnables with different tick vals
                    }
                }
            }
        }
        if (cpu && !gpu) {
            /* task can be mapped only to CPUs */
            log.debug(t.getName() + " can be mapped to 0 --" + (this.nbCPUs - 1));
            this.domains.put(t, PuType.CPU);
            if (!this.intervals.containsKey(PuType.CPU)) {
                this.intervals.put(PuType.CPU, new int[] { 0, this.nbCPUs - 1 });
            }
        } else if (gpu && !cpu) {
            /* task can be mapped only to GPUs */
            log.debug(t.getName() + " can be mapped to " + this.nbCPUs + "--" + (this.nbPUs - 1));
            this.domains.put(t, PuType.GPU);
            if (!this.intervals.containsKey(PuType.GPU)) {
                this.intervals.put(PuType.GPU, new int[] { this.nbCPUs, this.nbPUs - 1 });
            }
        } else if (defaultVal || (gpu && cpu)) {
            /* task can be mapped anywhere */
            log.debug(t.getName() + " can be mapped to 0 --" + (this.nbPUs - 1));
            this.domains.put(t, PuType._UNDEFINED_);
            if (!this.intervals.containsKey(PuType._UNDEFINED_)) {
                this.intervals.put(PuType._UNDEFINED_, new int[] { 0, this.nbPUs - 1 });
            }
        } else {
            /* Task can be mapped nowhere */
            log.fatal(t.getName() + " can be mapped nowhere");
        }
    }
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
    org.apache.log4j.BasicConfigurator.configure();
    Logger.getRootLogger().setLevel(Level.INFO);
    long startTime = System.currentTimeMillis();   

    //-----> You have created an instance of ia
    int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
    final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));  

//-----> You have passed the _same_ instance to all of the constructor calls
    Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
    Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
    Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);  
    ...    

 //---->lets move a bit down to the method that's called within the Callable  

private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {  
   ...    
  int firstIndex = 0;
   ...  
   int randomIndex = random.nextInt(iap.length - 1);  
   ...  
 //---> this part should make sure what you are stating, that "ID 1 should print array with first index in range 0 to 1." and this is correct
   if (randomIndex == firstIndex) {

        if (newIndexValue > stopRange) {
            newIndexValue = startRange;
        } else if (newIndexValue < startRange) {
            newIndexValue = stopRange;
        }

    }  else {
        if (newIndexValue > maximumNoOfCoreIndex) {
            newIndexValue = minimumNoOfCoreIndex;
        } else if (newIndexValue < minimumNoOfCoreIndex) {
            newIndexValue = maximumNoOfCoreIndex;
        }
    }
       ...
int[] ia_copy;  

public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
    this.model = model;  

    //----> create a copy like this:
    ia_copy=new int[ia.length];
    System.arraycopy( ia, 0, ia_copy, 0, ia.length );  

    this.nbCPUs = CommonUtils.getNumberofCPUs(model);
    // this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
    this.nbPUs = CommonUtils.getNumberofPUs(model);
    this.ID = ID;
    this.startRange = startRange;
    this.stopRange = stopRange;
    init();
}
@Override
public String call() {
...
while (System.currentTimeMillis() < endTime) {  
//----> ia to ia_copy 
        int[] currentMapping = generateTpuMappingWithRange(ia_copy , startRange, stopRange);  
...