• 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();
        }
        
    }
     
  • 相关阅读:
    jmeter如何连接数据库
    jmeter基础之录制篇
    php解压缩
    composer基本使用
    react组件之间的参数传递
    解决VMware Workstation 不可恢复错误: (vcpu-0)
    虚拟机vmware11装Mac ox 10.8 解决windows8.1下unlocker202 vmxsmc.exe已停止工作的问题
    Photoshop学习:打开PS之前需要...
    汇编语言之启航
    Markdown语法介绍
  • 原文地址:https://www.cnblogs.com/moris5013/p/11778388.html
Copyright © 2020-2023  润新知