【一】 并发容器基础 -- 1.7 模拟自己的阻塞队列MyQueue 代码

手写模拟一个自己的 阻塞队列 MyQueue

package com.example.demo.edu51;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

//定义一个 阻塞队列
public class MyQueue {

	
	// 1. 定义一个容器
	private final ArrayList<String> list = new ArrayList<>();
	
	private final LinkedList<String> ll = new LinkedList<>();
	
	// 2. 计数器
	// AtomicInteger 实现单个服务之间的原子性,支持并发,并发下保证单个服务的数据一致性,不会造成数据错误
	private final AtomicInteger count = new AtomicInteger(0);
	
	// 最大容量
	private final int maxSize;
	
	private final int minSize = 0;
	
	private  Object lock = new Object();
	
	public MyQueue (int size) {
		this.maxSize = size;
	}
	
	
	public void put(String s) {
		synchronized(lock) {
			// 如果容器容量已满,则线程等待
			while(count.get() == maxSize) {
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			// 跳出while循环,这说明容器中有位置可以加入新元素
			ll.add(s);
			count.getAndIncrement();// 等同于 i++ 
			System.out.println(" ++  "+s + "     "+count.get()+ "    "+Thread.currentThread().getName());
			// 容器有元素了, 唤醒 正在做 take 操作,等待(取走元素)中的线程
			lock.notify();
		}
	}
	
	
	public String take() {
		String temp = null;
		synchronized(lock) {
			// 如果容器中没有元素,wait
			while(count.get() == minSize) {
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			// count.get() != 0,容器中有元素了, 取走首位元素
			temp = ll.removeFirst();
			count.getAndDecrement(); // 等同于 i-- 
			System.out.println(" 	--  "+temp+ "     "+count.get()+ "    "+Thread.currentThread().getName());
			// 取走一个, 容器中有位置了, 唤醒真在做put操作的等待中的线程
			lock.notify();
		}
		
		
		return temp;
	}
	
	
	public int size() {
		return count.get();
	}
	
	public List<String> getQueue(){
		return ll;
	}
	
	
	
	
	
}

测试类:

package com.example.demo.edu51;

public class MyQueueTest {

	
	
	public static void main(String[] args) {
		MyQueue mq = new MyQueue(5);
		mq.put("1");
		mq.put("2");
		mq.put("3");
		mq.put("4");
		mq.put("5");
		
		System.err.println("size1 :  "+mq.size());
		
		Thread put1 = new Thread(new Runnable() {
			@Override
			public void run() {
				mq.put("put1_1");
				mq.put("put1_2");
				mq.put("put1_3");
				mq.put("put1_4");
			}
		},"put1");
		
		System.err.println("size2 :  "+mq.size());
		
		Thread put2 = new Thread(new Runnable() {
			@Override
			public void run() {
				mq.put("p2_1");
				mq.put("p2_2");
				mq.put("p2_3");
				mq.put("p2_4");
			}
		},"put2");
		
		
		Thread put3 = new Thread(new Runnable() {
			@Override
			public void run() {
				mq.put("p3_1");
				mq.put("p3_2");
				mq.put("p3_3");
				
				
			}
		},"put3");
		
		Thread put4 = new Thread(new Runnable() {
			@Override
			public void run() {
				mq.put("p4_1");
				mq.put("p4_2");
			}
		},"put4");
		
		put1.start();
		put2.start();
		put3.start();
		put4.start();
		
		// take **************************************************
		Thread take1 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				
			}
		},"take1");
		
		
		Thread take2 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
					Thread.sleep(1000);
					mq.take();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		},"take2");
		
		take1.start();
		take2.start();
		
		try {
			Thread.sleep(7000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.err.println(" 元素  "+ mq.getQueue().toString());
		
		
		
	}
	
	
}

控制台打印:

size1 :  5
 ++  1     1    main
 ++  2     2    main
 ++  3     3    main
 ++  4     4    main
 ++  5     5    main
size2 :  5
 	--  1     4    take2
 ++  put1_1     5    put1
 	--  2     4    take1
 ++  p3_1     5    put3
 	--  3     4    take1
 ++  p2_1     5    put2
 	--  4     4    take2
 ++  p3_2     5    put3
 	--  5     4    take2
 ++  p2_2     5    put2
 	--  put1_1     4    take1
 ++  p3_3     5    put3
 	--  p3_1     4    take1
 ++  put1_2     5    put1
 	--  p2_1     4    take2
 ++  p4_1     5    put4
 	--  p3_2     4    take2
 ++  p2_3     5    put2
 	--  p2_2     4    take1
 ++  put1_3     5    put1
 元素  [p3_3, put1_2, p4_1, p2_3, put1_3]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值