zoukankan      html  css  js  c++  java
  • 【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();
                }
            }
        }
    }
  • 相关阅读:
    HDU 5441 离线处理 + 并查集
    [转载]HDU 3478 判断奇环
    POJ 1637 混合图的欧拉回路判定
    [转载] 一些图论、网络流入门题总结、汇总
    UVA 820 --- POJ 1273 最大流
    [转载 ]POJ 1273 最大流模板
    POJ 3041 -- 二分图匹配
    2014西安现场赛F题 UVALA 7040
    UVA 12549
    割点、桥(一点点更新)
  • 原文地址:https://www.cnblogs.com/cutter-point/p/6042090.html
Copyright © 2011-2022 走看看