生产者和消费者问题-使用BlockingQueue来实现

使用BlockingQueue来实现

BlockingQueue可以称为是数据共享通道,主要用来实现不同线程之间的通信同步问题。BlockingQueue是一个借口,底层的实现是数组。BlockingQueue主要由两个方法take(),put()方法。BlockingQueue中内置了几个变量, ReentrantLock重入锁, 重入锁的搭档Condition类型的 notEmpty,Condition类型的 notFull。在take()方法中,如果共享区的数据为空的时候会让其他线程进行等待。在put()方法中,如果共享区的数据为已久超过容量的时候会让其他线程进行等待。
以下案例根据java高并发程序设计书籍实现
数据类:

public  final class PCData {
    private final int intData;
    public  PCData(int d){
        intData=d;
    }
    public PCData(String  d){
        intData=Integer.valueOf(d);
    }
    public int getIntData(){
        return intData;
    }

    @Override
    public String toString() {
        return "data:"+intData;
    }
}

生产者:

import java.util.Random;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Producer implements Runnable {
    private  volatile boolean isRunning=true;
    private BlockingDeque queue;
    //AtomicInteger是一种无锁的实现,基于CAS算法
    private static AtomicInteger count=new AtomicInteger();
    private static final int SlLEEPTIME=1000;
    public Producer(BlockingDeque queue) {
        this.queue = queue;
    }
    @Override
    public void run() {
        PCData data=null;
        Random r=new Random();
        System.out.println("start producer id="+Thread.currentThread().getId());
        while (isRunning){
            try {
                Thread.sleep(r.nextInt(SlLEEPTIME));
                data=new PCData(count.incrementAndGet());
                System.out.println(data+"is put into queue");
                if(!queue.offer(data,2, TimeUnit.SECONDS));{
                    System.out.println("failed to put data:"+data);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    }
    public void stop(){
        isRunning=false;
    }
}

消费者

import java.text.MessageFormat;
import java.util.Random;
import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable {
    private BlockingQueue queue;
    private static final int SLEEPTIME=1000;
    public Consumer(BlockingQueue queue){
        this.queue=queue;
    }
    @Override
    public void run() {
        System.out.println("start Consumer id="+Thread.currentThread().getId());
        Random r=new Random();
        while (true){
            try {
                PCData data=queue.take();
                if(null!=data){
                    int re=data.getIntData()*data.getIntData();
                    System.out.println(MessageFormat.format("{0}*{1}={2}",data.getIntData(),data.getIntData(),re));
                }
                Thread.sleep(r.nextInt(SLEEPTIME));
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }

        }
    }
}

测试类

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
public class Main1 {
    public static void main(String[] args) throws InterruptedException{
        LinkedBlockingDeque queue=new LinkedBlockingDeque(10);
        Producer producer1=new Producer(queue);
        Producer producer2=new Producer(queue);
        Producer producer3=new Producer(queue);
        Consumer consumer1=new Consumer(queue);
        Consumer consumer2=new Consumer(queue);
        Consumer consumer3=new Consumer(queue);
        ExecutorService service= Executors.newCachedThreadPool();
        service.execute(producer1);
        service.execute(producer2);
        service.execute(producer3);
        service.execute(consumer1);
        service.execute(consumer2);
        service.execute(consumer3);
        Thread.sleep(10*1000);
        producer1.stop();
        producer2.stop();
        producer3.stop();
        Thread.sleep(3000);
        service.shutdown();

    }
}

基于无锁的策略的实现CAS算法

CAS算法的过程大概是这样的,他包含三个参数,CAS(V,E,N),V表示要更新的变量,E表示预期的值,N表示新的值,仅当要更新的变量等于预期的变量的值得时候,才会将新的值赋值给需要更新的变量,如果预期的值和更新的变量不同,则说明其他的线程已经做了更新当前线程说明也不做

你可能感兴趣的:(生产者和消费者问题-使用BlockingQueue来实现)