gpt4 book ai didi

java - 从ArrayList多线程打印

转载 作者:行者123 更新时间:2023-12-03 12:59:01 25 4
gpt4 key购买 nike

我试图让记录器将所有日志消息从应用程序打印到控制台,并在将来打印一个外部文件。当我触发函数“dumpToConsole”时,它应该执行此操作。应该通过3个线程对所有3个线程都访问CopyOnWriteArrayList进行多线程处理。问题在于输出的顺序不正确,是应有的输出的三倍。而不是3条消息,我得到9。例如,我需要3个线程到所有单独的打印1,而不是每个线程都打印3。

请参阅以下我对此的实际实现。

我的主题:

public class LoggingThread extends Thread {
private boolean isStopped = false;
private CopyOnWriteArrayList<LogMessage> messages;

public LoggingThread(CopyOnWriteArrayList messages) {
this.messages = messages;
}

@Override
public void run() {
for (int i = 0; i < messages.size(); i++) {
writeMessageToConsole(messages.get(i).getMessageText(), messages.get(i).getLogLevel());
}
}

private synchronized void writeMessageToConsole(String message, LogLevel logLevel) {
System.out.println(message + " (" + logLevel + ")");
}
}

我的记录仪:
public class Logger implements ILogger {
private static ILogger instance = null;
private CopyOnWriteArrayList<LogMessage> messages = new CopyOnWriteArrayList<LogMessage>();
private LoggingThread thread1;
private LoggingThread thread2;
private LoggingThread thread3;

public static ILogger getInstance() {
if (instance == null) {
instance = new Logger();
}

return instance;
}

public CopyOnWriteArrayList<LogMessage> getMessages() {
return messages;
}

public void log(Exception ex) {
log(ex.getMessage(), LogLevel.FATAL);
}

public void log(String message, LogLevel logLevel) {
messages.add(new LogMessage(message, logLevel));
}

public LogMessage getLastLog() {
if(!messages.isEmpty()) {
return messages.get(messages.size() -1);
}

else {
return new LogMessage("", LogLevel.DEBUG);
}
}

public void dumpToConsole() {
log("TEST1", LogLevel.FATAL);
log("TEST2", LogLevel.DEBUG);
log("TEST3", LogLevel.FATAL);

thread1 = new LoggingThread(this.messages);
thread2 = new LoggingThread(this.messages);
thread3 = new LoggingThread(this.messages);

thread1.start();
thread2.start();
thread3.start();

try {
thread1.join();
thread2.join();
thread3.join();
}

catch (InterruptedException e) {
log(e.getMessage(), LogLevel.FATAL);
}

thread1.interrupt();
thread2.interrupt();
thread3.interrupt();
}
}

和我的消息类:
public class LogMessage {
private String messageText;
private LogLevel logLevel;

public LogMessage(String messageText, LogLevel logLevel) {
this.messageText = messageText;
this.logLevel = logLevel;
}

public LogLevel getLogLevel() {
return logLevel;
}

public String getMessageText() {
return messageText;
}
}

结果是:
TEST1 (FATAL)
TEST2 (DEBUG)
TEST3 (FATAL)
TEST1 (FATAL)
TEST1 (FATAL)
TEST2 (DEBUG)
TEST3 (FATAL)
TEST2 (DEBUG)
TEST3 (FATAL)

最佳答案

一个独特的非答案:忘记在这里使用3个线程。

The problem is that the output is not in order, and triple of what it should be. Instead of 3 messages I get 9.



当然。因为您要求三个3个线程来完成一个线程应该执行的工作,而每个线程又要执行相同的工作。

因此,首先:一旦您说出“多线程”,并且谈论打印列表内容,那么所有关于订购的赌注都将关闭。当然,每个线程将以正确的顺序打印消息,但是 没有控制T1是先打印所有消息,还是先打印一个消息,然后从T2打印3条消息,无论如何。 “未同步”线程的本质是:未定义的顺序。

然后:即使您添加了必要的步骤以某种方式“同步”线程,这样做也不会获得 ,而不会获得

内存中只有一个列表。有一个输出文件(或控制台)。使用多个线程来获取值并将它们放入文件并不能加快任何速度!它只会增加开销,并且可以看到:它会产生大量“同步”代码的需求。

关于java - 从ArrayList多线程打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54171086/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com