Я написал обычную библиотеку MyLogger на основе шаблона проектирования Observer. Я пытаюсь добиться этого: каждый раз, когда я вызываю writeLog(LOG_LEVEL,"Text")
я хочу, чтобы он выполнялся в новом потоке. Может кто-нибудь, пожалуйста, предложите, каков будет способ достичь этого. Как там, где я должен создавать потоки.
Так выглядит мой вызов Logger.
public class Logger extends Subject{
void writeLog(String type, String message)
{ setData(message);
notifyy(type);
}
}
И вот как я называю writeLog
appLogger.writeLog("ERROR", "This is error");
Вы можете использовать шаблон Producer-Consumer-Pattern следующим образом:
public class Logger {
/**
* The ExecutorService runs the Thread that processes the logs.
*/
private final ExecutorService loggingService = Executors.newSingleThreadExecutor();
/**
* A queue that contains the logs.
*/
final BlockingQueue<YourLogObject> logs = new LinkedBlockingQueue<>();
/**
* Creates a new Logger object and starts the Thread that processes the logs.
*/
public Logger() {
loggingService.submit(new Runnable() {
@Override
public void run() {
try {
for (;;) {
final YourLogObject log = logs.take();
// setData(log.getMessage());
// notify(log.getLevel());
}
} catch (final InterruptedException e) {
e.printStackTrace();
return;
}
}
});
}
/**
* Creates a new YourLogObject from the given parameters and puts it at the end of the queueu.
*/
public void writeLog(final String level, final String message) {
final YourLogObject log = new YourLogObject(level, message);
try {
logs.put(log);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
/**
*
*/
public void shutdown() {
loggingService.shutdownNow();
}
}
public class YourLogObject {
private final String level;
private final String message;
public YourLogObject(final String level, final String message) {
this.level = level;
this.message = message;
}
public String getLevel() {
return level;
}
public String getMessage() {
return message;
}
}
writeLog()
помещает новые журналы в эту очередь, а фоновый поток постоянно выводит сообщения из очереди. В подходе Стефана один поток создается для каждого вызова writeLog()
. Это может быть много накладных расходов.
Вы можете использовать ExecutorService
// Somewhere in your logging framework
ExecutorService service = Executors.new...(); // Choose the one you want
...
public MessageRelayingTask implements Runnable {
// private fields
...
public MessageRelayingTask(String type, String message) {
...
}
@Override
public void run() {
setData(message);
notifyy(type);
}
}
public class Logger extends Subject implements Runnable {
void writeLog(String type, String message) {
service.submit(new MessageRelayingTask(type, message));
}
}
Некоторые указатели, чтобы вы начали: