我有這樣的代碼:多線程會導致程序停止?
public void GenerateWtW() {
ExecutorService exec = Executors.newFixedThreadPool(30);
ConcurrentHashMap<String, Double> tf_idfCache = new ConcurrentHashMap<String, Double>();
ArrayList<String> allwords = getAllWords();
int no_docs = getNumberOfDocs();
int cnt = 0;
for (int i = 0; i < allwords.size(); i++) {
String word1 = allwords.get(i);
if (i < allwords.size() - 1) {
for (int j = i + 1; j < allwords.size(); j++) {
String word2 = allwords.get(j);
cnt++;
if (word1.equals(word2)) {
continue;
}
//System.out.println("[" + cnt + "] WtW Started: " + word1 + "," + word2 + " No of Docs: " + no_docs + " Total No of words: " + allwords.size());
WTWThread t = new WTWThread(tf_idfCache, word1, word2, this, no_docs, db);
exec.execute(t);
}
}
}
exec.shutdown();
}
這裏是線程的代碼:
private static class WTWThread implements Runnable {
private ConcurrentHashMap<String, Double> cacheRef;
private String word1, word2;
private WordRank workRankInstance;
private int no_docs;
private Database db;
public WTWThread(ConcurrentHashMap<String, Double> cacheRef, String word1, String word2, WordRank workRankInstance, int no_docs, Database db) {
this.cacheRef = cacheRef;
this.word1 = word1;
this.word2 = word2;
this.workRankInstance = workRankInstance;
this.no_docs = no_docs;
this.db = db;
}
@Override
public void run() {
double sum = 0;
for (int i = 1; i <= 10; i++) {
Double tf_idf1 = cacheRef.get(word1 + i);
if (tf_idf1 == null) {
tf_idf1 = workRankInstance.getTF_IDF(word1, i);
cacheRef.put(word1 + i, tf_idf1);
}
Double tf_idf2 = cacheRef.get(word2 + i);
if (tf_idf2 == null) {
tf_idf2 = workRankInstance.getTF_IDF(word2, i);
cacheRef.put(word2 + i, tf_idf2);
}
sum = sum + (tf_idf1 * tf_idf2);
}
double wtw = sum/no_docs;
String query = "INSERT INTO wtw(word1,word2,wtw) VALUES(?,?,?);";
try {
PreparedStatement ps = db.getConnection().prepareStatement(query);
ps.setString(1, word1);
ps.setString(2, word2);
ps.setDouble(3, wtw);
ps.executeUpdate();
ps.close();
} catch (SQLException ex) {
Logger.getLogger(WordRank.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
我的一切看起來不錯,但這裏是發生了什麼,當我運行該程序,它處理的第一幾百,然後突然停止!我檢查了系統監視器,java進程在內存使用中開始增長,並達到約1Gb,然後沒有任何反應。我想也許這是因爲我有太多的線程,我嘗試了4線程,但同樣的事情發生。然後,我想也許我應該在創建線程之前使用sleep(),並且它確實解決了問題,它像一個魅力一樣工作,但即使睡眠(1)也會讓程序非常慢!我檢查了我能想到的所有可能的事情!有什麼我在這裏失蹤?
這不是堆空間問題,我將2gb分配給堆。問題是線程增長如此之快,我認爲jvm無法處理它!因爲我說,然後我放了一個延遲之前,一切工作正常!沒有內存泄漏,沒有鎖定的情況。我認爲我需要對線程池做些什麼 – Tohid
你不是在創建線程,而是在創建Runnable對象,它應該分佈在固定數量的線程中(在你的例子中爲30)。他們可能在完成工作後不久收集垃圾。 – Slartibartfast