java多线程共同操作同一个队列,怎么实现?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程共同操作同一个队列,怎么实现?相关的知识,希望对你有一定的参考价值。

参考技术A

具体代码如下:

以下是两个线程:

import java.util.*;

public class Thread_List_Operation

//假设有这么一个队列

static List list = new LinkedList();

public static void main(String[] args)

Thread t;

t = new Thread(new T1());

t.start();

t = new Thread(new T2());

t.start();

//线程T1,用来给list添加新元素

class T1 implements Runnable

void getElemt(Object o)

Thread_List_Operation.list.add(o);

System.out.println(Thread.currentThread().getName() + "为队列添加了一个元素");

@Override

public void run()

for (int i = 0; i < 10; i++)

getElemt(new Integer(1));

//线程T2,用来给list添加新元素

class T2 implements Runnable

void getElemt(Object o)

Thread_List_Operation.list.add(o);

System.out.println(Thread.currentThread().getName() + "为队列添加了一个元素");

@Override

public void run()

for (int i = 0; i < 10; i++)

getElemt(new Integer(1));

//结果(乱序)

Thread-0为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Java多线程:阻塞队列与等待唤醒机制初探

文章目录

阻塞队列概述

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

阻塞队列基本使用

BlockingQueue

常见BlockingQueue有:

  • ArrayBlockingQueue: 底层是数组,有界
  • LinkedBlockingQueue: 底层是链表,无界.但不是真正的无界,最大为int的最大值

他们两个和List的实现子类有点像。

他们的继承结构如下:

BlockingQueue的核心方法:

核心方法:

方法说明
put(anObject)将参数放入队列,如果放不进去会阻塞
take()取出第一个数据,取不到会阻塞

其他方法(与List类似)

方法\\处理方式抛出异常返回特殊值一直阻塞超时退出
插入方法add(e)offer(e)put(e)offer(e,time,unit)
移除方法remove()poll()take()poll(time,unit)
检查方法element()peek()不可用不可用

多线程一般多用put与take

代码示例

class Demo02 
    public static void main(String[] args) throws Exception 
        // 创建阻塞队列的对象,容量为 1
        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);

        // 存储元素
        arrayBlockingQueue.put("糖果");

        // 取元素
        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take()); // 取不到会阻塞

        System.out.println("程序结束了");
    

程序没有结束,他会一直读取阻塞队列

阻塞队列实现等待唤醒机制

代码需求:

生产者类(Cooker):实现Runnable接口,重写run()方法,设置线程任务

  1. 构造方法中接收一个阻塞队列对象
  2. 在run方法中循环向阻塞队列中添加包子
  3. 打印添加结果

消费者类(Foodie):实现Runnable接口,重写run()方法,设置线程任务

  1. 构造方法中接收一个阻塞队列对象
  2. 在run方法中循环获取阻塞队列中的包子
  3. 打印获取结果

测试类(Demo):里面有main方法,main方法中的代码步骤如下

  1. 创建阻塞队列对象
  2. 创建生产者线程和消费者线程对象,构造方法中传入阻塞队列对象
  3. 分别开启两个线程

代码示例

package com.test;


import java.util.concurrent.ArrayBlockingQueue;

class Cooker extends Thread 

    private ArrayBlockingQueue<String> bd;

    public Cooker(ArrayBlockingQueue<String> bd) 
        this.bd = bd;
    

    @Override
    public void run() 
        while (true) 
            try 
                bd.put("糖果");
                System.out.println("厨师放入一个糖果");
             catch (InterruptedException e) 
                e.printStackTrace();
            
        
    


class Foodie extends Thread 
    private ArrayBlockingQueue<String> bd;

    public Foodie(ArrayBlockingQueue<String> bd) 
        this.bd = bd;
    

    @Override
    public void run() 
        while (true) 
            try 
                String take = bd.take();
                System.out.println("吃货将" + take + "拿出来吃了");
             catch (InterruptedException e) 
                e.printStackTrace();
            
        

    


class Demo 
    public static void main(String[] args) 
        // 一个阻塞队列代表一个桌子
        ArrayBlockingQueue<String> bd = new ArrayBlockingQueue<>(1);

        Foodie f = new Foodie(bd);
        Cooker c = new Cooker(bd);

        f.start();
        c.start();
    

以上是关于java多线程共同操作同一个队列,怎么实现?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA多线程用实现Runnable接口的方式创建线程

Java多线程:阻塞队列与等待唤醒机制初探

怎么实现springMVC 多线程并发

java 队列

多线程与循环队列

C# 多线程同步访问一个文件怎么处理