• 【JAVA并发编程实战】7、日志服务


    这里是一个应用项目使用生产消费模型的日志类

    package cn.study.concurrency;
    
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    import org.junit.Test;
    
    /**
     * 日志服务
     * @author xiaof
     *
     */
    public class LogWriter {
        private final BlockingQueue<String> queue;
        private final LoggerThread logger;
        private final static int CAPACITY = 500;
        private boolean isShutdown;  //停止线程
        
        
        
        public LogWriter() 
        {
            this.queue = new LinkedBlockingQueue<String>(CAPACITY);
            this.logger = new LoggerThread();
        }
        
        public void start()
        {
            //判断这个线程是否已经启动
            if(!logger.isAlive())
            {
                logger.start();
            }
        }
        
        public void log(String msg) throws InterruptedException
        {
            //放入日志队列并阻塞队列
            if(!isShutdown)
                queue.put(msg);
            else
                throw new IllegalStateException("日志开关没有打开");
        }
        
        public boolean isShutdown() {
            return isShutdown;
        }
    
        public void setShutdown(boolean isShutdown) {
            this.isShutdown = isShutdown;
        }
    
        private class LoggerThread extends Thread
        {
            public void run()
            {
                try 
                {
                    while(true)
                    {
                        //从队列中取出队列头数据,并输出,有必要并阻塞队列
                        System.out.println("这是日志:" + queue.take());
                    }
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }
            }
        }
        
        @Test
        public void test()
        {
            LogWriter log = new LogWriter();
            log.start();
            int i = 1;
            while(true)
            {
                try {
                    Thread.currentThread().sleep(2000);
                    //把日志放入队列
                    log.log("这是日志:" + i++);
                    
                    if(i == 3)
                    {
                        log.setShutdown(true);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }

    更加可靠的取消日志服务的操作

    package cn.study.concurrency;
    
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    import org.junit.Test;
    
    /**
     * 日志类添加可靠的取消操作
     * @author xiaof
     *
     */
    public class LogService {
        private final BlockingQueue<String> queue;
        private final LoggerThread loggerThread;
        private boolean isShutdown;
        //如果线程停止提交任务,线程不能停,先得吧剩余的任务提交结束
        private int reservations;
        private final static int CAPACITY = 500;
        
        public LogService() 
        {
            //队列长度
            this.queue = new LinkedBlockingQueue<String>(CAPACITY);
            this.loggerThread = new LoggerThread();
        }
        
        public void start()
        {
            //判断这个线程是否已经启动
            if(!loggerThread.isAlive())
            {
                loggerThread.start();
            }
        }
        
        public void log(String msg) throws InterruptedException
        {
            //放入日志队列并阻塞队列
            synchronized(this)
            {
                if(isShutdown)
                    throw new IllegalStateException("日志开关没有打开");
                ++reservations;
            }
            queue.put(msg);
        }
        
        public void stop()
        {
            synchronized(this)
            {
                isShutdown = true;
            }
            //中断线程
            loggerThread.interrupt();
        }
        
        private class LoggerThread extends Thread
        {
            public void run()
            {
                try 
                {
                    while(true)
                    {
                        try 
                        {
                            //对日志类上锁
                            synchronized(LogService.this)
                            {
                                if(isShutdown && reservations == 0)
                                {
                                    break;//停止线程
                                }
                            }
                            //取出日志信息
                            String msg = queue.take();
                            //提交成功一条,对阻塞的数据计数减少一条
                            synchronized(LogService.this)
                            {
                                --reservations;
                            }
                            System.out.println(msg);
                        } 
                        catch (InterruptedException e) 
                        {
                            e.printStackTrace();
                        }
                    }
                } 
                finally
                {
                    System.out.println("日志结束..........");
                }
            }
        }
        
        @Test
        public void test()
        {
            LogService log = new LogService();
            log.start();
            int i = 1;
            while(true)
            {
                try {
                    Thread.currentThread().sleep(2000);
                    //把日志放入队列
                    log.log("这是日志:" + i++);
                    
                    if(i == 3)
                    {
                        log.stop();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 相关阅读:
    Nebula3的Input系统
    Nebula3学习笔记(7): 脚本系统
    项目经理成长日记(4)——态度决定一切
    Nebula3学习笔记(2): 核心库
    Nebula3学习笔记(1): 序
    魔兽争霸的地图验证漏洞和作弊图原理,兼谈魔兽联机机制[转载]
    Nebula3的多线程架构
    项目经理成长日记(5)——五指有长短,能力各不同
    Nebula3资源子系统
    Nebula3的场景管理
  • 原文地址:https://www.cnblogs.com/cutter-point/p/6042090.html
Copyright © 2020-2023  润新知