使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞

如题:

使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。
实现这么一个队列,并写一个测试代码,使他工作在多线程的环境下,证明,它的工作是正确的。给出程序和运行的截图。

Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构

Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接 口。

Queue的实现
1、没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口
  内置的不阻塞队列: PriorityQueue 和 ConcurrentLinkedQueue
  PriorityQueue 和 ConcurrentLinkedQueue 类在 Collection Framework 中加入两个具体集合实现。 
  PriorityQueue 类实质上维护了一个有序列表。加入到 Queue 中的元素根据它们的天然排序(通过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。
  ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大 小,          ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。
2)实现阻塞接口的:
  java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是立即从队列中添加或者删除元素,线程执行操作阻塞,直到有空间或者元素可用。
五个队列所提供的各有不同:
  * ArrayBlockingQueue :一个由数组支持的有界队列。
  * LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
  * PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。
  * DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
  * SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

add        增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常
  remove   移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
  element  返回队列头部的元素             如果队列为空,则抛出一个NoSuchElementException异常
  offer       添加一个元素并返回true       如果队列已满,则返回false
  poll         移除并返问队列头部的元素    如果队列为空,则返回null
  peek       返回队列头部的元素             如果队列为空,则返回null
  put         添加一个元素                      如果队列满,则阻塞
  take        移除并返回队列头部的元素     如果队列为空,则阻塞

remove、element、offer 、poll、peek 其实是属于Queue接口。 

先添加三个类,在运行main方法验证:

ps:当时想把其他两个类都写在一起遇到错误,最后分开写,实例化不会出问题;

enclosing instance of type ThreadQueue (e.g. x.new A() where x is an instance of ThreadQueue)

解释地址:https://blog.csdn.net/u012965373/article/details/41488695

package com.cdy.mvc.threadtest;

import java.util.LinkedList;
import java.util.Queue;

public class ThreadQueue extends Thread{
	private static final int maxLenth = 10;

    static Object lock = new Object();
    private Integer i = 0;

	private Queue<Object> queue = new LinkedList<Object>();

	public  void add() {
		synchronized (lock) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			if (queue.size() == maxLenth) {
				try {
					System.out.println("队列满了当前list长度:" + queue.size());
					lock.wait();
				} catch (InterruptedException e) {
					System.out.println("队列满了当前list长度:" + queue.size());
					e.printStackTrace();
				}
			}
			queue.add(i++);
			System.out.println("放入队列成功" + i);
			lock.notifyAll();
		}
	}

	public  Integer get() {
		 synchronized (lock) {
	            try {
					Thread.sleep(1000);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
	            if(queue.size()==0){
	                try {
	                	 System.out.println("队列空了当前list长度:"+queue.size());
	                    lock.wait();
	                } catch (InterruptedException e) {
	                    System.out.println("队列空了当前list长度:"+queue.size());
	                    lock.notifyAll();
	                }
	                return null;
	            }
	            Integer poll = (Integer) queue.poll();
	            System.out.println("移除i值:"+poll);
	            lock.notifyAll();
	            return poll;
	        }

	}
	
	public static void main(String[] args) {
			ThreadQueue queue = new ThreadQueue();
	        Thread add1 = new AddThread(queue,"生产者1");
	        Thread add2 = new AddThread(queue,"生产者2");
	        Thread add3 = new AddThread(queue,"生产者3");
	        Thread get1 = new GetThread(queue,"消费者1");
	        Thread get2 = new GetThread(queue,"消费者2");

	        add1.start();add2.start();add3.start();
	        get1.start();get2.start();
	

	}
}
package com.cdy.mvc.threadtest;

public class AddThread extends Thread{
	ThreadQueue q;
    public AddThread(ThreadQueue q,String name){
        super(name);
        this.q = q;
    }

    @Override
    public void run() {
        for(int i=0;i<4;i++){
            q.add();
        }
    }

}
package com.cdy.mvc.threadtest;

public class GetThread extends Thread {
	ThreadQueue q;
    public GetThread(ThreadQueue q,String name){
        super(name);
        this.q = q;
    }
    @Override
    public void run() {
        while(true){
            q.get();
        }
    }
}

测试结果:

放入队列成功1
放入队列成功2
放入队列成功3
放入队列成功4
移除i值:0
移除i值:1
移除i值:2
移除i值:3
队列空了当前list长度:0
队列空了当前list长度:0
放入队列成功5
放入队列成功6
放入队列成功7
放入队列成功8
放入队列成功9
放入队列成功10
放入队列成功11
放入队列成功12
移除i值:4
移除i值:5
移除i值:6
移除i值:7
移除i值:8
移除i值:9
移除i值:10
移除i值:11
队列空了当前list长度:0
队列空了当前list长度:0

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值