Java多线程之队列Quene-yellowcong

来源:互联网 发布:网络销售股票怎么加人 编辑:程序博客网 时间:2024/06/05 12:49

通过notify和wait实现java的多线程队列模型,主要是控制共同操作的List集合一致性,同时设计了队列的大小,队列有take和push方法,take获取List集合的第一个元素,push添加元素,通过AtomicInteger 实现计数操作

Java队列模型

package com.yellowcong.queue.demo;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;/** * 创建日期:2017年10月5日 <br/> * 创建用户:yellowcong <br/> * 功能描述:   */public class Queue {    //集合    private List<Object> list = new ArrayList<Object>();    //计数器,通过原子类计数    private AtomicInteger count = new AtomicInteger(0);    //锁对象    private static final Object LOCK = new Object();    private Integer maxSize;    public Queue(Integer maxSize) {        super();        this.maxSize = maxSize;    }    //获取数据    public Object take(){        synchronized (LOCK) {            while(count.get() <= 0 ){                try {                    LOCK.wait();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            //当满足的情况            Object result = list.get(0);            list.remove(0);            count.decrementAndGet();            LOCK.notify();            System.out.println(Thread.currentThread().getName()+"取出元素"+result.toString());            return result;        }    }    //添加数据    public void push(Object obj){        synchronized (LOCK) {            while(count.get() >= this.maxSize){                try {                    LOCK.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            list.add(obj);            //加            count.incrementAndGet();            System.out.println(Thread.currentThread().getName()+"放入元素"+obj.toString());            LOCK.notify();        }    }    /**     * 获取队列大小     * 创建日期:2017年10月5日<br/>     * 创建用户:yellowcong<br/>     * 功能描述:     * @return     */    public Integer getCount(){        return count.get();    }}

测试类

package com.yellowcong.queue.demo;/** * 创建日期:2017年10月5日 <br/> * 创建用户:yellowcong <br/> * 功能描述:   */public class QueueTest {    public static void main(String[] args) throws InterruptedException {        final Queue queue = new Queue(5);        Thread th1 = new  Thread(new Runnable() {            public void run() {                // TODO Auto-generated method stub                queue.push("test1");                queue.push("test2");                queue.push("test3");                queue.push("test4");                queue.push("test5");                //这个是第6个元素,这个地方会添加不进去,会等线程 将数据取出后,才可以接着放                queue.push("test6");                System.out.println(Thread.currentThread().getName()+"\t当前队列长度"+queue.getCount());            }        });        Thread th2 = new Thread(new Runnable() {            public void run() {                // TODO Auto-generated method stub                for(int i=0;i<5;i++){                    queue.take();                }            }        });        //先获取元素,发现获取不到        th2.start();        //然后线程1 添加元素        th1.start();        Thread.sleep(1000);        System.out.println("队列长度"+queue.getCount());    }}

运行结果

从结果可以看出,这个list队列中,添加元素后,就直接唤醒了另外一个线程的操作,他们之间是相互的交叉 执行的,并不是执行完一个,然后再去执行取出队列的操作

Thread-0放入元素test1Thread-1取出元素test1Thread-0放入元素test2Thread-1取出元素test2Thread-0放入元素test3Thread-1取出元素test3Thread-0放入元素test4Thread-1取出元素test4Thread-0放入元素test5Thread-0放入元素test6Thread-1取出元素test5Thread-0    当前队列长度1队列长度1