zoukankan      html  css  js  c++  java
  • wait()、notify()、notifyAll()方法的理解

    wait()表示把线程挂起,挂起的时候会自动释放锁。

    notify() 随机的选择一个在指定对象上挂起的线程激活。

    notifyAll() 激活指定对象上挂起的所有线程

    条件队列:一组等待线程集合,能够通过某种方式来等待对应的条件为真。条件队列中的元素是一个正在等待相关条件的线程。

        通过条件队列构建高可响应的状态依赖类,条件等待存在三元关系 加锁、wait、一个条件谓词(包含多个状态变量) ,状态变量由一个锁保护

         在测试条件谓语之前必须先获得对象的锁。锁对象和条件队列对象(即调用wait()和notify()方法的对象)必须是同一个对象。

    如下实现自定义有界缓存实现

         基类代码

    package com.lifeStudy.algorith;
    
    public abstract class BaseBoundedBuffer<V> {
    
        private final V[] buf;
        private int tail;
        private int head;
        private int count;
    
        protected BaseBoundedBuffer(int capacity) {
            //还可以通过直接new Object[]数组,等到需要具体化时候才 强制转换单个元素
            buf = (V[]) new Object[capacity];//泛型擦除,其实就是(Object[])转换
        }
    
    
        protected synchronized final void doPut(V v) {
            buf[tail] = v;
            if (++tail == buf.length) {
                tail = 0;
            }
            count++;
        }
    
        protected synchronized final V doTake() {
            V rs = buf[head];
            buf[head] = null;
            if (++head == buf.length) {
                head = 0;
            }
            count--;
            return rs;
        }
    
    //下面是两个状态变量,队列是否满;队列是否为空 通过内置锁对象this
    public synchronized final boolean isFull() { return count == buf.length; } public synchronized final boolean isEmpty() { return count == 0; } }

    通过wait()实现条件队列

    package com.lifeStudy.algorith;
    
    
    public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {//条件队列
    
        protected BoundedBuffer(int capacity) {
            super(capacity);
        }
    
        public synchronized void put(V v) throws InterruptedException {
    
            while (isFull()) {
                System.out.println(Thread.currentThread().getId() + " put竞争失败,挂起");
                this.wait();
                System.out.println(Thread.currentThread().getId() + " put被唤醒,二次激活");
            }
            doPut(v);
            this.notifyAll();//唤醒所有在this对象上挂起的线程
        }
    
        public synchronized V take() throws InterruptedException {
            while (isEmpty()) {
                System.out.println(Thread.currentThread().getId() + " get竞争失败,挂起");
                this.wait();//线程挂起,放开锁synchronized中this对象。
                System.out.println(Thread.currentThread().getId() + " get被唤醒,二次激活");
            }
            V v = doTake();
            this.notifyAll();//唤醒所有在this对象上挂起的线程
            return v;
        }
    
        public static void main(String... args) throws InterruptedException {
    
            BoundedBuffer<Integer> integerBoundedBuffer = new BoundedBuffer<Integer>(12);
    //        new Thread(new Consummer(integerBoundedBuffer)).start();
    //        TimeUnit.SECONDS.sleep(10);
            new Thread(new Producer(integerBoundedBuffer)).start();
            //通过下面可以看到  调用wait挂起线程时会释放锁.
    //        new Thread(new Producer(integerBoundedBuffer)).start();
    
    
    
        }
    
        private static class Consummer implements Runnable {
    
            private final BoundedBuffer bf;
    
            public Consummer(BoundedBuffer bf) {
                this.bf = bf;
            }
    
            public void run() {
                try {
                    while (true) {
                        bf.take();
                        System.out.println("get");
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    
    
        private static class Producer implements Runnable {
            private final BoundedBuffer bs;
    
            protected Producer(BoundedBuffer bs) {
                this.bs = bs;
            }
    
            public void run() {
                try {
                    while (true) {
                        bs.put(123);
                        System.out.println("put");
                    }
    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    
    }
  • 相关阅读:
    ArrayList和LinkedList的区别
    线程的基本概念、线程的基本状态以及状态之间的关 系
    当一个线程进入一个对象的一个synchronized方法后, 其它线程是否可进入此对象的其它方法?
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.thinkplatform.dao.UserLogDao' available: expected at least 1 bean which qualifies as autowi
    IDEA设置热部署
    spring的核心组件及作用(一)
    解决Linux启动redis时出现提示权限不够问题
    Struts自动装配和四种放入Session作用域的方式
    Struts第一个案例搭建
    当List<String> list =new ArrayList<String>(20); 他会扩容多少次
  • 原文地址:https://www.cnblogs.com/09120912zhang/p/8617681.html
Copyright © 2011-2022 走看看