我正在撰寫一個 rss 媒體抓取器,我parallelStream()的一個s 導致未關閉的執行緒。
它們都是Daemon Thread [ForkJoinPool.commonPool-worker-xx]執行緒。
我能發現的唯一區別是兩個示例都是從不同的執行緒呼叫的。這可能是問題嗎?即使當我嘗試啟動一個新的 Thread().start 時,也parallelStream()沒有ForkJoinPool關閉所有執行緒。而且我還嘗試使用簡單的物件,例如ArrayList<int>具有相同的結果。這是主執行緒之外的一種想要的行為嗎?
或者它只是檔案中描述的行為(粗體部分):
ForkJoinPool 與其他型別的 ExecutorService 的主要區別在于采用了作業竊取:池中的所有執行緒嘗試查找并執行提交給池和/或由其他活動任務創建的任務(如果不存在,則最終阻塞等待作業) .
public class MainRoutine {
public static void startRoutine(SubReddit subReddit) {
ArrayList<Entry> rssEntry = RSSgrab.pullRss(new SubReddit("pics", true, null));
rssEntry.parallelStream().forEach(System.out::println); //produces unclosed threads
System.out.println(Thread.currentThread().getName()); //prints AWT-EventQueue-0
}
public static void main(String[] args) {
ArrayList<Entry> rssEntry = RSSgrab.pullRss(new SubReddit("pics", true, null));
rssEntry.parallelStream().forEach(System.out::println); //this does not produce unclosed threads
System.out.println(Thread.currentThread().getName()); //prints main
//my bad, does also produce unclosed threads but the runtime is so short that I did not notice ofc
}
}
入門級
public class Entry {
String user;
String userUri;
String id;
String uri;
String date;
String title;
private ArrayList<String> media = new ArrayList<String>();
public Entry(String user, String userUri, String id, String uri, String date, String title) {
this.user = user;
this.userUri = userUri;
this.id = id;
this.uri = uri;
this.date = date;
this.title = title;
}
@Override
public String toString() {
return "Entry [user=" user ", userUri=" userUri ", id=" id ", uri=" uri ", date=" date
", title=" title ", media=" getMedia().stream().map(s -> s "; ").reduce("", String::concat) "]";
}
public ArrayList<String> getMedia() {
return media;
}
public void setMedia(ArrayList<String> media) {
this.media = media;
}
}

uj5u.com熱心網友回復:
基本上......你正在嘗試解決一個不是問題的問題。常見的 fork-join 池是托管池。JVM 負責處理它。
如果這對您來說真的很重要,那么壞訊息是您可能對此無能為力。公共池將忽略shutdown()并shutdownNow()呼叫。這是設計使然。
有一個技巧可以讓您創建自定義ForkJoinPool并在其中運行您的流。請參閱Java 8 并行流中的自定義執行緒池。完成后,您可以關閉池以使執行緒消失。
但是……這可能是個壞主意。重用現有池或公共池更有效。創建和銷毀執行緒是昂貴的。重復執行此操作是因為您重復創建和銷毀池是低效的。
公共ForkJoinPool不應被視為執行緒泄漏。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/361202.html
