안녕하세요. 재귀. .pdf URL 수확을하려고 해요. 그리고 ConcurrentModificationException 받고 있어요. 어떻게 이런 일이 있는지 이해하지 못하고 동시성에 대해 많이 몰라요. ; 이것이 어떻게 일어나고 어떻게 고정 될 수 있는지에 대한 약간의 통찰력에 크게 감사 할 것입니다. 주요 통화와URL 수확기 동시성 문제, ConcurrentModificationException
public class urlHarvester {
private URL rootURL;
private String fileExt;
private int depth;
private HashSet<String> targets;
private HashMap<Integer, LinkedList<String>> toVisit;
public urlHarvester(URL rootURL, String fileExt, int depth) {
this.rootURL = rootURL;
this.fileExt = fileExt;
this.depth = depth;
targets = new HashSet<String>();
toVisit = new HashMap<Integer, LinkedList<String>>();
for (int i = 1; i < depth + 1; i++) {
toVisit.put(i, new LinkedList<String>());
}
doHarvest();
}
private void doHarvest() {
try {
harvest(rootURL, depth);
while (depth > 0) {
for (String s : toVisit.get(depth)) {
toVisit.get(depth).remove(s);
harvest(new URL(s),depth-1);
}
depth--;
}
} catch (Exception e) {
System.err.println(e);
e.printStackTrace();
}
for (String s : targets) {
System.out.println(s);
}
}
private void harvest(URL url, int depth) {
try {
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
Scanner scanner = new Scanner(new BufferedInputStream(inputStream));
java.lang.String source = "";
while (scanner.hasNext()) {
source = source + scanner.next();
}
inputStream.close();
scanner.close();
Matcher matcher = Pattern.compile("ahref=\"(.+?)\"").matcher(source);
while(matcher.find()) {
java.lang.String matched = matcher.group(1);
if (!matched.startsWith("http")) {
if (matched.startsWith("/") && url.toString().endsWith("/")) {
matched = url.toString() + matched.substring(1);
} else if ((matched.startsWith("/") && !url.toString().endsWith("/"))
|| (!matched.startsWith("/") && url.toString().endsWith("/"))) {
matched = url.toString() + matched;
} else if (!matched.startsWith("/") && !url.toString().endsWith("/")) {
matched = url.toString() + "/" + matched;
}
}
if (matched.endsWith(".pdf") && !targets.contains(matched)) {
targets.add(matched);System.out.println("ADDED");
}
if (!toVisit.get(depth).contains(matched)) {
toVisit.get(depth).add(matched);
}
}
} catch (Exception e) {
System.err.println(e);
}
}
클래스 :
urlHarvester harvester = new urlHarvester(new URL("http://anyasdf.com"), ".pdf", 5);
많은 : 당신은 당신의 수집에서 직접 제거하기의 반복자를 대신 사용할 수 있습니다
:
이
당신이toVisit
HashMap
에서 항목을 제거하려고 할 때 무슨 일이 일어나고 코드 이 문제가 발생한 정확한 행과 전체 소스 파일에 대한 링크를 게시해야합니다. 나는 문제가'doHarvest()'메소드에 있다고 가정한다. 컬렉션을 반복하고 컬렉션에서 요소를 동시에 제거 할 수는 없습니다. 그 때 당신은'ConcurrentModificationException'을 얻습니다. –