簡體   English   中英

連接隊列中的Java多線程死鎖

[英]Java multithreading deadlock in Connection queue

我寫了一個小的Java程序來從網站上抓取信息。 我基本上下載了一個包含本月新聞ID的Excel文件,並將它們添加到查詢表中的數據庫中。 之后,我通過請求具有先前ID的頁面作為參數來開始抓取,使用jsoup解析頁面並將信息保存到數據庫中的另一個表中。

除此ConnectionManager類外,其他所有操作均按預期進行

public class ConnectionManager {

public static final int MAX_CONNECTIONS = 50;

private ArrayList<Runnable> mActiveThreads = new ArrayList<Runnable>();
private ArrayList<Runnable> mQueuedRunnables = new ArrayList<Runnable>();

private static ConnectionManager instance;

//Singleton
public static ConnectionManager getInstance() {
    if (instance == null) {
        System.out.println("Started Connection mQueuedRunnables " + new Date());
        instance = new ConnectionManager();
    }
    return instance;
}

//Adds new Runnable to the queue
public void push(Runnable runnable) { 
    mQueuedRunnables.add(runnable);
    if (mActiveThreads.size() < MAX_CONNECTIONS)
        startNext();
}

//Starts a Thread with the next Runnable in the queue
private void startNext() {
    if (!mQueuedRunnables.isEmpty()) {
        Runnable next = mQueuedRunnables.get(0);
        mQueuedRunnables.remove(0);
        mActiveThreads.add(next);

        Thread thread = new Thread(next);
        thread.start();
    } else if (mActiveThreads.size() == MAX_CONNECTIONS) {
        System.out.println("FINISHED " + new Date());
    }
}

//Callback method called when a Thread finishes its execution,
//Runnable is removed from queue and startNext() called
public void didComplete(Runnable runnable) {
    synchronized(mActiveThreads) {
        mActiveThreads.remove(runnable);

        if (mActiveThreads.size() < MAX_CONNECTIONS)
            startNext();
    }
}

}

push()所有Runnables每一個我需要做的連接,這是應該有50級永久性運行Threads ,直到隊列清空。 如您所見,它保留兩個Lists :一個用於隊列,另一個用於活動Threads push()Runnables只是簡單的Runnables ,它們創建HttpURLConnection ,解析HTML並將數據插入數據庫中。

據我所知,這應該起作用,但我懷疑某個地方存在死鎖,因為在某個時刻,活動Threads開始下降,直到停滯為止。 我一直在調試代碼,發現盡管mActiveThreads保持為50,但JVM中的實際活動Threads卻越來越低。

我所做的最新更改是synchronized塊,但似乎完全沒有幫助。 有人可以指出該代碼在哪里失敗嗎? 還是如何自己找出答案? 我嘗試使用VisualVM,但可以看到Threads數下降,但無法弄清楚為什么:-(

好吧,事實證明它根本與多線程無關。 問題在於某些連接未建立,並且從InputStream讀取有時在某些時候失敗(我想這與打開許多並發連接有關)。

一旦我使用了setConnectTimeout()和setReadTimeout(),問題就消失了。 我還將每個連接置於3個迭代循環內,因此在觸發超時的情況下,該連接將重試2次。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM