首页 课程 师资 教程 报名

举例说明Java阻塞队列

  • 2022-10-17 12:52:31
  • 972次 动力节点

Java阻塞队列这个,就是当队列中没有数据的时候,线程读取的话会等待。当队列中的数据满的时候,线程添加数据的时候,也会等待。

有个例子很生动形象,往盘子里面放鸡蛋,只能放固定数目的。盘子里面没有鸡蛋,无法从中拿出来。当盘子里满了,也放不进去。直到被拿出去才能在放。

代码如下,这里设置的是一个盘子最多放10个鸡蛋:

package com.thread.two;
import java.util.ArrayList;
import java.util.List;
public class Plate {
    List<Object> eggs=new ArrayList<Object>();public synchronized Object getEgg(){while(eggs.size()==0){
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Object egg=null;
        for (int i = 0; i < 10; i++) {
            egg=eggs.get(i);
            System.out.println("拿到鸡蛋.........");
        }
        //Object egg=eggs.get(0);
        eggs.clear();
        notify();
        //System.out.println("拿到鸡蛋.........");
        return egg;
    }    
    public synchronized void putEgg(Object egg){
while(eggs.size()>9){
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        eggs.add(egg);
        notify();
        System.out.println("放入鸡蛋.........");
    }    
    static class AddThread extends Thread{
        private Plate plate;
        private Object egg=new Object();
        public AddThread(Plate plate){
            this.plate=plate;
        }
        public void run(){
            for (int i = 0; i < 1000; i++) {
                plate.putEgg(egg);
            }
        }
    }    
    static class GetThread extends Thread{
        private Plate plate;
        public GetThread(Plate plate){
            this.plate=plate;
        }
        public void run(){
            for (int i = 0; i < 1000; i++) {
                plate.getEgg();
            }
        }
    }    
    public static void main(String[] args) throws InterruptedException {
        Plate plate=new Plate();
        Thread add=new Thread(new AddThread(plate));
        Thread get=new Thread(new GetThread(plate));
        add.start();
        get.start();
        add.join();
        get.join();
        System.out.println("测试结束");
    }    
}

这个例子很形象,用线程实现了上面所说的。

java现在有concurrent包,里面有很多现成的可以用的类,很多是线程安全的,这样,像上面写的put或者get,都不需要自己写同步方法了,这些类已经包装好了。

这里有一个ArrayBlockingQueue的例子,和上面实现的差不多。

首先是两个线程,分别是put和get。

ThreadPut:

package com.thread.three;
import java.util.concurrent.ArrayBlockingQueue;
public class ThreadPut implements Runnable{
    private ArrayBlockingQueue<String> abq=null;
    public ThreadPut(ArrayBlockingQueue<String> abq){
        this.abq=abq;
    }
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            System.out.println("要向队列中存数据了");
            try {
                Thread.sleep(1000);
                abq.put("hi");
                System.out.println("存入后,数据一共为:"+abq.size());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

ThreadGet:

package com.thread.three;
import java.util.concurrent.ArrayBlockingQueue;
public class ThreadGet extends Thread {
    ArrayBlockingQueue<String> abq=null;
    public ThreadGet(ArrayBlockingQueue<String> abq){
        this.abq=abq;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("我要从队列中取数据了");
            String msg=null;
            if (abq.size()>0) {
                msg=abq.remove();
            }
            System.out.println("队列中取得的数据为:"+msg+",队列中还有一共:"+abq.size());
        }
    }
}

测试类:

public class ArrayBlockQueueApp {    
    public static void main(String[] args) {
        ExecutorService  es=Executors.newCachedThreadPool();
        ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<String>(10);
        ThreadGet tGet=new ThreadGet(abq);
        Thread tPut=new Thread(new ThreadPut(abq));
        es.execute(tGet);
        es.execute(tPut);
    }
}

这些队列放消息的话挺不错的。如果大家想了解更多相关知识,不妨来关注一下本站的Java队列,里面还有更丰富的知识等着大家去学习,相信对大家一定会有所帮助的。

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交