zoukankan      html  css  js  c++  java
  • Guarded Suspension设计模式

    Guarded Suspension 设计模式可以保证,当线程在访问某个对象时,发现条件不满足,就挂起等待条件满足时再次访问
    public class GuardedSuspensionQueue {
        
        // 定义存放Integer类型的queue
        private final LinkedList<String> queue = new LinkedList<String>();
    
        // 定义queue的最大容量为5
        private  final int LIMIT = 5;
    
        public  static final Random random = new Random(System.currentTimeMillis());
    
        // 往queue中插入数据,如果queue中的元素超过了最大容量,则会陷入阻塞
        public void offer(String data) {
            synchronized (this) {
                // 判断queue的当前元素是否超过了LIMIT
                while (queue.size() >= LIMIT) {
                    // 挂起当前线程,使其陷入阻塞
                    System.out.println("向queue中添加元素,元素个数超过了限制,"+Thread.currentThread().getName()+"被挂起!");
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                // 插入元素并且唤醒take线程
                queue.addLast(data);
                this.notifyAll();
            }
        }
    
        
        // 从队列中获取元素,如果队列此时为空,则会使当前线程阻塞
        public String take()  {
            synchronized (this) {
                // 判断如果队列为空
                while (queue.isEmpty()) {
                    // 则挂起当前线程
                    System.out.println(Thread.currentThread().getName()+"从queue中取出元素,元素个数为0,被挂起!");
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return null;
                    }
                }
                //removeFirst不会返回null值,queue没有元素会抛出异常
                String res =  queue.removeFirst();
                // 通知offer线程可以继续插入数据了
                this.notifyAll();
                return  res;
            }
        }
    
        
        public static void main(String[] args) throws InterruptedException {
            
            GuardedSuspensionQueue queue = new GuardedSuspensionQueue();
            
            TakerThread takerThread = new TakerThread(queue,"【线程A】");
            takerThread.start();
            
            Thread.sleep(2000);
            
            // 创建3个生产线程向queue中添加数据
            IntStream.rangeClosed(1, 3).forEach(i -> {
                new Thread(() -> {
                    for (int j = 1; j <= 5; j++) {
                        queue.offer("【线程"+i+"】放入的"+j);
                    }
                    try {
                        Thread.sleep(random.nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
            });
            
            Thread.sleep(10_000);
            
            takerThread.close();
        }
    
    }
    
    class TakerThread extends Thread{
        private volatile boolean  close = false;
        private  GuardedSuspensionQueue   queue ;
        TakerThread(GuardedSuspensionQueue queue,String name){
            this.queue = queue;
            setName(name);
        }
        @Override
        public void run() {
            while(!close) {
                String item = queue.take();
                if(item == null) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "从queue中取出数据:" + item);
                try {
                    Thread.sleep(GuardedSuspensionQueue.random.nextInt(1000));
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    break;
                }
            }
        }
        
        public void close() {
            this.close = close;
            this.interrupt();
        }
        
    }
     
  • 相关阅读:
    Python爬虫模拟登录的github项目
    pandas常用数据清洗方法
    5分钟了解swagger
    OpenAuth.Net.landv分支之旅开始制作CRM系统
    捷信达会员管理系统SQL语句相关
    EXcel vba 获取批注信息
    西软报表处理语句相关
    中软酒店管理系统CSHIS操作手册_数据结构_数据字典
    金蝶k3密码批量修改
    K3 WISE 开发插件《SQL语句WHERE查询-范围查询/模糊查询》
  • 原文地址:https://www.cnblogs.com/moris5013/p/11778388.html
Copyright © 2011-2022 走看看