簡體   English   中英

在Java中使用System.out.println的多個線程

[英]Multiple threads using System.out.println in Java

我有一個多線程Java應用程序,它將收到的有關消息的信息輸出到控制台以進行調試。 每次應用程序收到消息時,它都會在消息上調用System.out.println(String)

我遇到的問題是,如果應用程序充滿了消息, System.out.println()輸出錯誤的信息(如舊的緩沖區信息)。 這讓我想知道是否存在線程問題,其中多個線程一次調用println函數,並且沒有正確刷新緩沖區。

在我的主程序(線程)中,我有一些效果:

while(iterator.hasNext())
{
    SelectionKey key = iterator.next();

    channel.receive(buffer);     // The buffer is a ByteBuffer.
    buffer.flip();

    new Thread(new ThreadToPrintTheMessage(buffer)).start();

    buffer.clear();

    iterator.remove();
}

在我的帖子中,我有一些效果:

@Override
public void run()
{
    System.out.println(message);
    System.out.flush();   // I have better results with this.  But, it doesn't
                          // fully resolve the issue.
}

有沒有一種簡單的方法可以讓多個線程一次打印到控制台而不包含包含舊信息的緩沖區?

謝謝

編輯:更新主線程中的代碼,以更好地代表我的程序正在做什么。

synchronized (System.out) {
    System.out.println(message);
    System.out.flush();
}

這里可能有一些示例代碼來解決問題:

while(iterator.hasNext())
{
    SelectionKey key = iterator.next();

    channel.receive(buffer);     // The buffer is a ByteBuffer.
    buffer.flip();
    byte[] bytes = new byte[buffer.limit()];  // copy buffer contents to an array
    buffer.get(bytes);
    // thread will convert byte array to String
    new Thread(new ThreadToPrintTheMessage(bytes)).start();

    buffer.clear();

    iterator.remove();
}

我沒有時間檢查println源,確保它始終是線程安全的(你可以,如果你想),但你確定你的println錯了嗎? 很可能代碼運行的時間與您想象的完全不同。 線程經常掛在鎖上或者只是被調度程序忘記了,所以你認為應該運行A,B,C,D可以運行B,C,D,A。然后你想知道為什么println搞砸了,打印到底是什么你認為先跑。 這是一個非常簡單的例子。 您希望多線程發生的事情與發生的事情之間的差異可能真的令人震驚。 通常,線程與核心比率越高,它就越差。 單核機器總能做出與您期望相反的一切。

而且你甚至不需要多個線程來解決這個問題。 我的第一個顛簸來自事件隊列(在Windows 3.1上),它沒有分享我對什么時候應該運行的看法。 我花了一段時間才發現這些消息是混亂的,因為操作系統對它們應該如何運行有着截然不同的想法。

System.out.println和flush可能會有一些細微之處我不知道,但即使你完成了所有工作,也要注意那些線程對自己有相反的想法。 即便記錄器也無法解決您的所有問題。

您應該使用Java.util.logging或其他一些日志框架來實現此目的。

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/logging/Logger.html

import java.util.logging.Logger;
....
Logger log = Logger.getLogger("com.something.something");
....
log.log(Level.Info, "Message");

暫無
暫無

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

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