簡體   English   中英

使用線程的Java生產者使用者永不終止

[英]Producer Consumer in Java using threads never terminates

我有一個用Java實現的生產者-消費者問題,我希望生產者線程運行特定的時間,例如1天,將對象放入BlockingQueue推文,通過Twitter4j-從Twitter Streaming API流到消費者,線程從隊列中使用這些對象並將它們寫入文件。 從大文件中逐一讀取了3000萬用戶ID的 PC邏輯,其中生產者是FileTask,消費者是CPUTask(檢查第一個答案;我的方法使用相同的迭代/ try-catch blocks ) 。 當然,我相應地修改了實現。 我的主要功能是:

public static void main(String[] args) {
    ....

    final int threadCount = 2;

    // BlockingQueue with a capacity of 200
    BlockingQueue<Tweet> tweets = new ArrayBlockingQueue<>(200);

    // create thread pool with given size
    ExecutorService service = Executors.newFixedThreadPool(threadCount);

    Future<?> f = service.submit(new GathererTask(tweets));
    try {
        f.get(1,TimeUnit.MINUTES); // Give specific time to the GathererTask
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        f.cancel(true); // Stop the Gatherer
    }

    try {
        service.submit(new FileTask(tweets)).get(); // Wait til FileTask completes
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

    service.shutdownNow();

   try {
        service.awaitTermination(7, TimeUnit.DAYS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

現在的問題是,盡管它確實傳輸了tweet並將其寫入文件,但它永遠不會終止,也永遠不會到達f.cancel(true)部分。 要使其正常工作,我應該更改什么? 另外,您能否在回答中解釋線程邏輯在哪里出了問題,所以我可以從我的錯誤中學到什么? 先感謝您。

這些是我的PC類的run()函數:

制片人:

@Override
    public void run() {
        StatusListener listener = new StatusListener(){
            public void onStatus(Status status) {
                try {
                    tweets.put(new Tweet(status.getText(),status.getCreatedAt(),status.getUser().getName(),status.getHashtagEntities()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentTread.interrupt(); // Also tried this command
            }
        }

        public void onException(Exception ex) {
            ex.printStackTrace();
        }
    };
    twitterStream.addListener(listener);
    ... // More Twitter4j commands
}

消費者:

public void run() {
    Tweet tweet;
    try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("out.csv", true)))) {
        while(true) {
            try {
                // block if the queue is empty
                tweet = tweets.take();
                writeTweetToFile(tweet,out);

            } catch (InterruptedException ex) {
                break; // GathererTask has completed
            }
        }
        // poll() returns null if the queue is empty
        while((tweet = tweets.poll()) != null) {
            writeTweetToFile(tweet,out);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

您應該檢查您的Thread類是否正在處理InterruptedException,否則,它們將永遠等待。 可能會有所幫助。

暫無
暫無

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

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