使用JUC类,以及非JUC类实现阻塞队列
1:使用JUC类的ReentrantLock实现阻塞队列
1.1:主要使用lock.newCondition() 来声明两个Condition ,使用Condition的await 实现阻塞,使用signalAll来实现唤醒。Condition 的await,signalAll类似于Object的wait,notifyAll 比较相似;后续会专门列一篇文件说一下Condition 。
package com.xiao.bloackQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BlockingQueueJuc<E> {
/**
* 使用Condition实现阻塞队列
*/
private int count;//队列内元素数量
private int maxcount = 1<<30;//默认最大值
private List<E> containers;//使用List作为队列存储元素
private final Lock lock = new ReentrantLock();//声明一个锁
private final Condition takeCondition = lock.newCondition();
private final Condition putCondition = lock.newCondition();
/**
* 有默认大小的构造函数
* @param maxcount
*/
public BlockingQueueJuc(int maxcount){
this.maxcount = maxcount;
this.count = 0;
containers = new ArrayList<>(maxcount);//直接初始化到最大的数量
}
/**
* 使用默认大小的构造函数
*/
public BlockingQueueJuc(){
this.count = 0;
containers = new ArrayList<>(16);//直接初始化到最大的数量
}
/**
* 往队列放入元素
* @param node
*/
public void put(E node){
try{
lock.lockInterruptibly();
if(count==maxcount){//线程满了,则进行等待
putCondition.await();
}
count++;
containers.add(node);
System.out.println("+++++++++++++++++添加参数,目前队列共有参数为:"+count+"+++++++++++++++++++++++++");
takeCondition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* 从队列中取出元素
* @return
*/
public E take(){
try{
lock.lockInterruptibly();
if(count==0){
takeCondition.await();
}
count--;
E node = containers.remove(0);
System.out.println("-------------------------取出参数,目前队列共有参数为:"+count+"-------------------------");
takeCondition.signalAll();
putCondition.signalAll();
return node;
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} finally {
lock.unlock();
}
}
}
1.2:代码测试
package com.xiao.bloackQueue;
import java.util.ArrayList;
import java.util.List;
public class BlockingQueueJucThread {
public static void main(String[] args){
BlockingQueueJuc blockingQueueJuc = new BlockingQueueJuc();
List<Thread> list = new ArrayList<>();
for(int i=0;i<100;i++){
Thread thread = new Thread(new Produer(blockingQueueJuc));
list.add(thread);
}
for(int i=0;i<100;i++){
Thread thread = new Thread(new Consumer(blockingQueueJuc));
list.add(thread);
}
list.forEach(e->{
e.start();
});
}
}
class Consumer implements Runnable{
BlockingQueueJuc blockingQueueJuc;
public Consumer(BlockingQueueJuc blockingQueueJuc){
this.blockingQueueJuc = blockingQueueJuc;
}
@Override
public void run() {
Object take = blockingQueueJuc.take();
}
}
class Produer implements Runnable{
BlockingQueueJuc blockingQueueJuc;
public Produer(BlockingQueueJuc blockingQueueJuc){
this.blockingQueueJuc = blockingQueueJuc;
}
@Override
public void run() {
blockingQueueJuc.put(Thread.currentThread().getName());
}
2:使用synchronized实现阻塞队列
2.1:synchronized实现阻塞队列代码实现
package com.xiao.bloackQueue;
import java.util.ArrayList;
import java.util.List;
public class BlockingQueueNotJuc<E> {
private int count;//目前集合中拥有的数量
private int maxcount = 1<<30;//最大的数量(也可以初始化的时候指定)
private List<E> containers;
private final Object takeObject = new Object();//空
private final Object putObject = new Object();//满
volatile boolean notalil = false;
/**
* 指定大小的队列初始化
* @param maxcount
*/
public BlockingQueueNotJuc(int maxcount){
containers = new ArrayList<>(maxcount);//直接初始化到最大的数量
this.count = 0;
this.maxcount = maxcount;
}
/**
* 非指定大小的默认初始化队列
*/
public BlockingQueueNotJuc(){
containers = new ArrayList<>(16);//预初始化为16
this.count = 0;
}
/**
* 往阻塞队列放数据
* @param node
*/
public void put(E node){
synchronized(putObject){
try {
if(count == maxcount){//说明已经满,需要将队列阻塞
putObject.wait();
}
this.count++;
containers.add(node);
// if(count==1){
// takeObject.notifyAll();
// }
if(notalil){
synchronized (takeObject) {
System.out.println("唤醒阻塞线程");
notalil = false;
takeObject.notifyAll();
}
}
System.out.println("+++++++++++++++++添加参数,目前队列共有参数为:"+count+"+++++++++++++++++++++++++");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 获取阻塞队列的内容
* @return
*/
public E toke(){
synchronized(takeObject){
try {
if(count<=0){//说明已经空了,需要将获取操作阻塞
notalil = true;
System.out.println(Thread.currentThread().getName()+":进入阻塞状态");
takeObject.wait();
}
System.out.println(Thread.currentThread().getName()+"--------------获取参数,目前队列共有参数为:"+count+"---------------------");
this.count--;
E node = containers.get(0);
containers.remove(0);
if(count==(maxcount-1)){
synchronized (putObject) {
putObject.notifyAll();
}
}
return node;
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
}
}
2.2:测试代码
package com.xiao.bloackQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BlockQueueThread {
public static void main(String[] args){
BlockingQueueNotJuc queueNotJuc = new BlockingQueueNotJuc();
ExecutorService executorService = Executors.newFixedThreadPool(40);
List<Thread> threads = new ArrayList<>();
for(int i=0;i<20;i++){
Thread thread = new Thread(new PutThread(queueNotJuc,i+""));
threads.add(thread);
thread.start();
}
for(int i=0;i<20;i++){
Thread thread = new Thread(new TakeThread(queueNotJuc,i+""));
threads.add(thread);
thread.start();
}
threads.forEach(e->{
// executorService.submit(e);
//executorService.execute(e);
});
}
static class TakeThread implements Runnable{
BlockingQueueNotJuc queueNotJuc;
String name;
TakeThread(BlockingQueueNotJuc queueNotJuc,String name){
this.queueNotJuc = queueNotJuc;
this.name = name;
}
@Override
public void run() {
for(int i=0;i<100;i++){
queueNotJuc.toke();
}
}
}
static class PutThread implements Runnable{
BlockingQueueNotJuc queueNotJuc;
String name;
PutThread(BlockingQueueNotJuc queueNotJuc,String name){
this.queueNotJuc = queueNotJuc;
this.name = name;
}
@Override
public void run() {
for(int i=0;i<100;i++){
queueNotJuc.put("线程名:"+name);
}
}
}
}