Search code examples
javamultithreadingdesign-patternsthread-safety

Threads and Observer Pattern


I am trying to write Observe pattern in Java in multithread program to develop own logging program. My program is used in any Java class and can create the Logger class, and write a message to the logger. Logger class will call the logger manager class , which is a Singleton class and it also have the private class which is thread, on execution a scheduler runs, So I kept that execution in the private constructor.

private void LoggerManager() { 
    System.out.println("IN CONSTRUCTOR"); 
    executorThread.submit(new CreateLoggerFileForSpecifiedTime());
}

static LoggerManager getInstance() {
    if (LOGMANAGER == null) {
        synchronized (LoggerManager.class) {
            if(LOGMANAGER == null){
                System.out.println("IN MANAGER");
                LOGMANAGER = new LoggerManager();
            }
        }
    }
    return LOGMANAGER;
}

Next there is a method in the LoogerManager "writeMessageToLog".

void writeMessageToLog(String componantName, String message, 
                     Calendar messageCreationTime) { 
    LoggerDetails logDetails = new LoggerDetails(componantName, message,
                     messageCreationTime); 
    LogInitiater logIntiater = new LogInitiater(logDetails, noticeOfLoggerChange, 
                     noticeOfMessageAdded); 
    executorThread.submit(logIntiater); 
} 

LogIntitiater is a thread which is added the LogWriter to two Subject's, One subject is a scheduler I have pasted above i.e a Timer runs for every specified time and notfiies LogWriter the need to create a new log file while the other purpose is when a message is added in the queue. Code is not working as expected: * scheduler code is not running, I tried with execute as well. That private constructor is not being called * thread initiater is not always called * observe pattern: I have used J2SE interfaces i.e Observable and Observe and they are not working as expected

Please help me.


Solution

  • Producer - Consumer way for Logger (INCOMPLETE AND NOT FULLY TESTED) - will leave that to you

    This is just for the demonstration purpose and shows one way of doing ASYNCHRONOUS logging

    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    
    class Logger extends Thread{
            private static Logger logger = null;
            private BlockingQueue<String> logRequests;
    
            private Logger(){
                logRequests = new ArrayBlockingQueue<String>(10000);
            }
    
            public static Logger getLogger(){
                if(logger == null){
                    synchronized (Logger.class) {
                        logger = new Logger();
                        logger.start();
                    }
                }
                return logger;
            }
    
    
            @Override
            public void run() {
                System.out.println("Starting to log");
                while(true){
                    try {
                        System.out.println(logRequests.take());
                    } catch (InterruptedException e) {
                        //interrupted so stop logging
                        System.out.println("Logger exiting");
                        break;
                    }
                }
            }
    
            public void info(String logMessage){
                //not taken care of the case when queue becomes full
                //will leave it to you
                logRequests.add(logMessage);
            }
        }
    

    Main class

    public static void main(String[] args) {
            Logger.getLogger().info("This is info message");
    
            System.out.println("I am free");
    
    
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
                //stop the log
            Logger.getLogger().interrupt();
    
        }