를 생산하는 내 문제의 소스 인 ConcurrentApp 클래스 내 코드입니다 : 일부를 포함하는 클래스 DCP에 대한자바 프로그램의 실행 스레드를 더 추가하고 여기에 다른 결과
class Processor implements Runnable {
private int id;
private Integer interaction;
private Set<Integer> subset;
private Set<Integer> y;
private Object lock = new Object();
public DCP<BSN> dcp;
public Processor(int id, Integer interaction, Set<Integer> subset, DCP<BSN> dcp, Set<Integer> y) {
this.id = id;
this.interaction = interaction;
this.subset= subset;
this.dcp = dcp;
this.y = y;
}
public void run() {
//System.out.println("Starting: " + this.id);
if (this.y.contains(this.interaction)){
this.subset.add(this.interaction);
processRemoval(this.subset);
}
//System.out.println("Completed: " + this.id);
}
public void processRemoval(Set<Integer> collection){
synchronized(Processor.lock) {
for (Iterator<Integer> iter = this.y.iterator(); iter.hasNext();) {
int element = iter.next();
while(element != this.interaction){
element = iter.next();
}
this.dcp.increaseScore(collection);
if (!collection.contains(this.interaction)) {
System.out.println(element + " WAS REMOVED by thread " + this.id);
iter.remove();
}
}
}
}
}
public class ConcurrentApp {
public void multiRP (DCP<BSN> dcp, int threads) {
ConcurrentHashMap<Integer,Boolean> x = new ConcurrentHashMap<Integer,Boolean>();
ConcurrentHashMap<Integer,Boolean> z = new ConcurrentHashMap<Integer,Boolean>();
Set<Integer> y = (Set<Integer>) Collections.newSetFromMap(x);
y.addAll(dcp.PA);
Set<Integer> zeta = (Set<Integer>) Collections.newSetFromMap(z);
ExecutorService executor = Executors.newFixedThreadPool(threads);
int i =1;
while ((y.size() > i) && (i <= dcp.R)){
for (Iterator<Integer> iterator = y.iterator(); iterator.hasNext();){
zeta.addAll(y);
Integer interaction = iterator.next();
zeta.remove(interaction);
ArrayList<Set<Integer>> subsets = dcp.getSubsets(zeta, i);
for (int j = 0; j< subsets.size(); j++){
executor.submit(new Processor(j, interaction, subsets.get(j), dcp, y));
}
}
i++;
}
executor.shutdown();
System.out.println("All tasks submitted");
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(y);
dcp.PA = new ArrayList<Integer>(y);
System.out.println("All tasks completed");
}
}
및 관련 코드 도우미 기능, 여기에 있습니다 :
public class DCP<E> extends CondInd<E> {
public final int R; //assumed maximum # of nodes blocking any node from target
public ArrayList <Integer> PA; //set of all parents of the target node (should be static)
//public Node NULL; //NULL is model with no parents of target (should be final static)
public E scoreType = null;
public ScoringFunction<? super E> scoringFunction;
public double calcScore(E sT, Set<Integer> parentIndices) {
ArrayList<Integer> list = new ArrayList<Integer>(parentIndices);
return this.scoringFunction.score(sT, list);
}
public double calcScore(E sT, ArrayList<Integer> parentIndices) {
return this.scoringFunction.score(sT, parentIndices);
}
//helper for actual subsets method
private void getSubsets(ArrayList<Integer> input, int length, int start_index, Set<Integer> acc, ArrayList<Set<Integer>> sol){
//base case
if (acc.size() == length){
sol.add(new HashSet<>(acc));
return;
}
//recursive solution
if (start_index == input.size()) return;
int x = input.get(start_index);
acc.add(x);
//first recursion
getSubsets(input, length, start_index+1, acc, sol);
acc.remove(x);
//second recursion, after x removed
getSubsets(input, length, start_index+1, acc, sol);
}
//different arguments and returns a list of subsets
public ArrayList<Set<Integer>> getSubsets(ArrayList<Integer> input, int length){
ArrayList<Set<Integer>> sol = new ArrayList<>();
getSubsets(input, length, 0, new HashSet<Integer>(), sol);
return sol;
}
//different arguments and returns a list of subsets
public ArrayList<Set<Integer>> getSubsets(Set<Integer> input, int length){
ArrayList<Set<Integer>> sol = new ArrayList<>();
ArrayList<Integer> copy = new ArrayList<Integer>(input);
getSubsets(copy, length, 0, new HashSet<Integer>(), sol);
return sol;
}
//removes the element from the input that increases the score by the highest value
public void increaseScore(Set<Integer> input){
int index = -1;
double score = calcScore(scoreType,input);
List<Integer> list = new ArrayList<Integer>(input);
for (Integer element : list) {
ArrayList<Integer> copy_list = new ArrayList<Integer>(list);
copy_list.remove(element);
if (calcScore(scoreType,copy_list) > score){
index = list.indexOf(element);
score = calcScore(scoreType,copy_list);
}
}
if (index != -1)
input.remove(list.get(index));
}
public DCP(int maximumNodes, E scoreType, ScoringFunction<? super E> scoringFunction, ArrayList<Integer> parents){
this.R = maximumNodes;
this.scoreType = scoreType;
this.scoringFunction = scoringFunction;
this.PA = parents;
}
}
내가 스레드 = 1, 내 인쇄 제표를 기준으로 내 콘솔에 다음과 같은 출력을 받게과 ConcurrentApp에 내 코드를 실행 :
All tasks submitted
0 WAS REMOVED by thread 1
1 WAS REMOVED by thread 0
2 WAS REMOVED by thread 0
3 WAS REMOVED by thread 0
4 WAS REMOVED by thread 1
5 WAS REMOVED by thread 0
6 WAS REMOVED by thread 0
[7, 8]
All tasks completed
Program completed in :22 seconds
여기서 첫 번째 숫자는 내 목록에서 제거 된 정수에 해당합니다 (예 : "0 스레드 2에 의해 제거되었습니다"는 값 0이 주 목록 y에서 제거되었음을 의미합니다. 이 출력은 삭제해야하는 모든 값이 한 번 삭제되고이 경우 삭제되지 않는 유일한 두 값이어야하는 예상 결과 [7, 8]를 제공하므로 의미가 있습니다.
그러나, 나는> 1 개 스레드와 내 코드를 실행할 때, 나는 다음과 같은 출력을 얻을 : 당신이 볼 수 있듯이 여러 스레드가 결정하기 때문에, 어떤 경우에는 같은 값을 여러 번 제거
All tasks submitted
0 WAS REMOVED by thread 2
1 WAS REMOVED by thread 1
2 WAS REMOVED by thread 0
2 WAS REMOVED by thread 1
3 WAS REMOVED by thread 1
3 WAS REMOVED by thread 2
4 WAS REMOVED by thread 0
4 WAS REMOVED by thread 1
5 WAS REMOVED by thread 0
5 WAS REMOVED by thread 1
6 WAS REMOVED by thread 0
6 WAS REMOVED by thread 1
7 WAS REMOVED by thread 1
7 WAS REMOVED by thread 2
8 WAS REMOVED by thread 1
8 WAS REMOVED by thread 0
[]
All tasks completed
Program completed in :0 seconds
을 값을 제거해야했습니다. 또 다른 문제점은 여러 스레드를 사용할 때 어떤 이유에서든 7과 8을 주 목록에서 삭제해야한다고 잘못 결정하기 때문에 [7, 8] 대신 [7]을 사용하여 결과가 변경된다는 것입니다. 나는 잠금 필드에 정적을 추가하여 다중 스레드 삭제이 문제를 해결 :
private static Object lock = new Object();
그러나, 지금은 내가 스레드의 수를 증가 할 때 런타임이 변경되지 않는 문제가 있습니다. 정적 첨가 후 실> = 1을 사용의 출력은 아래와 같다 : 스레드
All tasks submitted
0 WAS REMOVED by thread 1
1 WAS REMOVED by thread 1
2 WAS REMOVED by thread 1
3 WAS REMOVED by thread 0
4 WAS REMOVED by thread 1
5 WAS REMOVED by thread 0
6 WAS REMOVED by thread 0
[7, 8]
All tasks completed
Program completed in :22 seconds
수는 런타임이 향상되지 않고 I 정확한 결과를 얻는다. 이 결과와 런타임은 1 개의 thread를 사용하든 많든간에 정확히 동일합니다.
질문 : 제가보기에는 두 가지 해결책이 있습니다 :
1) 잠금에 static 키워드를 제거하고를 건너 다른 스레드를 말할 제거를 수행하는 스레드에 대한 방법을 찾아 제거 된 값
2) 정적 키워드를 유지하고 더 많은 정보가있을 때 내 프로그램이 오직 하나의 스레드 만 사용하는 이유를 알아보십시오.
모든 아이디어를 매우 높이 평가합니다.
모든 코드가이 질문과 관련이 있다고 생각하기는 어렵습니다. 그것을 [mcve]로 축소 할 수 있습니까? – shmosel
@shmosel 첫 번째 코드 블록은 문제에 필요한 주요 코드입니다. 이전에 유사한 코드를 게시 한 적이 있으며, 작업을 쉽게하기 위해 두 번째 코드 블록을 포함 시키라는 지시를 받았습니다. 첫 번째 코드 블록에 초점을 맞추고 첫 번째 블록의 일부 기능/클래스를 이해해야하는 경우 두 번째 코드 블록을 참조하십시오. 이것은 완전한 예제지만 믿을만한 예제는 코드를 실행하는 데 필요한 다양한 패키지와 종속성으로 인해 훨씬 많은 코드가 필요합니다. –