Выполнение каждого запроса регистрации в другом потоке

1

Я написал обычную библиотеку 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");
  • 0
    Почему бы вам не использовать модель производитель / потребитель?
  • 0
    Еще несколько обсуждений об асинхронном ведении журнала на stackoverflow.com/questions/17018420/asynchronous-logging
Теги:
multithreading
observer-pattern

2 ответа

1
Лучший ответ

Вы можете использовать шаблон 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;
    }

}
  • 0
    Спасибо за ответ. Подскажите, пожалуйста, чем это концептуально отличается от ответа Стефана?
  • 0
    С этим решением у вас есть только один фоновый поток, который работает постоянно. У вас есть одна очередь сообщений. Метод writeLog() помещает новые журналы в эту очередь, а фоновый поток постоянно выводит сообщения из очереди. В подходе Стефана один поток создается для каждого вызова writeLog() . Это может быть много накладных расходов.
1

Вы можете использовать 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));
    }
}

Некоторые указатели, чтобы вы начали:

  • 0
    Большое спасибо за ответ Стефан. Есть ли альтернативные способы? Если да, можете ли вы предложить преимущества, если вы делаете это одним способом, а не другим?
  • 0
    Но почему новая тема для каждого сообщения? Похоже, много накладных расходов. Разве не достаточно одного фонового потока, который берет из общей очереди?
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню