通过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放入元素test1
Thread-1取出元素test1
Thread-0放入元素test2
Thread-1取出元素test2
Thread-0放入元素test3
Thread-1取出元素test3
Thread-0放入元素test4
Thread-1取出元素test4
Thread-0放入元素test5
Thread-0放入元素test6
Thread-1取出元素test5
Thread-0 当前队列长度1
队列长度1