使用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<PCData> queue;
//AtomicInteger是一种无锁的实现,基于CAS算法
private static AtomicInteger count=new AtomicInteger();
private static final int SlLEEPTIME=1000;
public Producer(BlockingDeque<PCData> 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<PCData> queue;
private static final int SLEEPTIME=1000;
public Consumer(BlockingQueue<PCData> 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<PCData> queue=new LinkedBlockingDeque<PCData>(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表示新的值,仅当要更新的变量等于预期的变量的值得时候,才会将新的值赋值给需要更新的变量,如果预期的值和更新的变量不同,则说明其他的线程已经做了更新当前线程说明也不做