多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享(生产者线程向队列中放数据,消费者线程从队列中取线程消费)。
首页 我们得有一个消费的模型,至少我们得知道生产什么,消费什么吧。
class product {
private String productID;
private String productName;
public String getProductID() {
return productID;
}
public void setProductID(String productID) {
this.productID = productID;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public product(String productID, String productName) {
super();
this.productID = productID;
this.productName = productName;
}
public product() {
super();
}
}
然后要有一个生产者线程,消费者线程
生产者线程往一个队列里面放数据(product),消费者线程从队列里取数据(product) 所以 我们需要一个 队列 来作为一个容器。
BlockingQueue<product> productQueue = new LinkedBlockingQueue<product>(20);
生产者线程
这里的put方法在队列满的情况下线程会阻塞
class produceThread implements Runnable{
public produceThread(BlockingQueue<product> productQueue) {
// TODO Auto-generated constructor stub
this.productQueue = productQueue;
}
public static String randSix(){
String []baseStr = {"1","2","3","4","5","6","7","8","9","0",
"a","b","c","d","e","A","B"};
String str="";
for(int i = 0 ;i<6;i++){
int index = ((int)(100*Math.random()))%baseStr.length;
str += baseStr[index];
}
return str;
}
BlockingQueue<product> productQueue;
public void run() {
// TODO Auto-generated method stub
product p = new product(randSix(),Thread.currentThread().getName()+"线程生产");
try {
productQueue.put(p);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程生产了一个产品,产品ID "+p.getProductID());
}
}
消费者线程
take方法在 队列里面没数据的时候会阻塞
class consumeThread implements Runnable{
BlockingQueue<product> productQueue;
public consumeThread(BlockingQueue<product> productQueue) {
// TODO Auto-generated constructor stub
this.productQueue = productQueue;
}
public void run() {//把这个 product从队列里取出来
// TODO Auto-generated method stub
try {
product p = productQueue.take();
System.out.println("消费线程:"+Thread.currentThread().getName()+"线程消费了一个产品,产品ID "+p.getProductID());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
整个代码
ScheduledExecutorService service = Executors.newScheduledThreadPool(3);
这行代码构造了一个线程池 执行定时任务 这个线程池里有3个线程
package com.dlh.concurrent;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class blockingQueueService{
public static void main(String[] args) {
// TODO Auto-generated method stub
@SuppressWarnings("unused")
BlockingQueue<product> productQueue = new LinkedBlockingQueue<product>(20);
//每隔1秒定时执行
ScheduledExecutorService service = Executors.newScheduledThreadPool(3);
service.scheduleAtFixedRate(new produceThread(productQueue), 1, 1,TimeUnit.SECONDS);
//每隔2秒定时执行
ScheduledExecutorService service1 = Executors.newScheduledThreadPool(3);
service1.scheduleAtFixedRate(new produceThread(productQueue), 1, 2,TimeUnit.SECONDS);
//每隔3秒定时执行
ScheduledExecutorService service2 = Executors.newScheduledThreadPool(3);
service2.scheduleAtFixedRate(new produceThread(productQueue), 1, 3,TimeUnit.SECONDS);
//每隔4秒定时执行
ScheduledExecutorService service3 = Executors.newScheduledThreadPool(3);
service3.scheduleAtFixedRate(new consumeThread(productQueue), 1, 4,TimeUnit.SECONDS);
}
}
class produceThread implements Runnable{
public produceThread(BlockingQueue<product> productQueue) {
// TODO Auto-generated constructor stub
this.productQueue = productQueue;
}
public static String randSix(){
String []baseStr = {"1","2","3","4","5","6","7","8","9","0",
"a","b","c","d","e","A","B"};
String str="";
for(int i = 0 ;i<6;i++){
int index = ((int)(100*Math.random()))%baseStr.length;
str += baseStr[index];
}
return str;
}
BlockingQueue<product> productQueue;
public void run() {
// TODO Auto-generated method stub
product p = new product(randSix(),Thread.currentThread().getName()+"线程生产");
try {
productQueue.put(p);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程生产了一个产品,产品ID "+p.getProductID());
}
}
class consumeThread implements Runnable{
BlockingQueue<product> productQueue;
public consumeThread(BlockingQueue<product> productQueue) {
// TODO Auto-generated constructor stub
this.productQueue = productQueue;
}
public void run() {//把这个 product从队列里取出来 要不要考虑 对这个product处理的结果 比如处理成功再 从take取一个product
// TODO Auto-generated method stub
try {
product p = productQueue.take();
System.out.println("消费线程:"+Thread.currentThread().getName()+"线程消费了一个产品,产品ID "+p.getProductID());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class product {
private String productID;
private String productName;
public String getProductID() {
return productID;
}
public void setProductID(String productID) {
this.productID = productID;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public product(String productID, String productName) {
super();
this.productID = productID;
this.productName = productName;
}
public product() {
super();
}
}
下面我们运行下代码
pool-2-thread-1线程生产了一个产品,产品ID 41184a
pool-1-thread-1线程生产了一个产品,产品ID a84d56
消费线程:pool-4-thread-1线程消费了一个产品,产品ID 41184a
pool-3-thread-1线程生产了一个产品,产品ID 0113A7
pool-1-thread-1线程生产了一个产品,产品ID A619a5 ----------pool-1 的第一个线程
pool-1-thread-2线程生产了一个产品,产品ID 11eAe9
pool-2-thread-1线程生产了一个产品,产品ID 5bb9a2
pool-1-thread-2线程生产了一个产品,产品ID Bec28A ----------pool-1 的第二个线程
pool-3-thread-1线程生产了一个产品,产品ID B5a017
pool-1-thread-2线程生产了一个产品,产品ID c8A0d8
pool-2-thread-2线程生产了一个产品,产品ID 91Ad21
消费线程:pool-4-thread-1线程消费了一个产品,产品ID a84d56
pool-1-thread-2线程生产了一个产品,产品ID b07A53
pool-1-thread-2线程生产了一个产品,产品ID 974c25
pool-2-thread-1线程生产了一个产品,产品ID 6B36bB
pool-3-thread-2线程生产了一个产品,产品ID 70d49b
pool-1-thread-1线程生产了一个产品,产品ID b67cbe
pool-2-thread-3线程生产了一个产品,产品ID 223261
消费线程:pool-4-thread-2线程消费了一个产品,产品ID 0113A7
pool-1-thread-1线程生产了一个产品,产品ID cad53e
pool-3-thread-1线程生产了一个产品,产品ID b30e6B
pool-1-thread-1线程生产了一个产品,产品ID ed6a76
pool-1-thread-1线程生产了一个产品,产品ID 702c31
pool-2-thread-3线程生产了一个产品,产品ID 1757b1
pool-1-thread-1线程生产了一个产品,产品ID Ab22c2
pool-1-thread-3线程生产了一个产品,产品ID a3a567 ----------pool-1 的第三个线程
消费线程:pool-4-thread-1线程消费了一个产品,产品ID A619a5
pool-2-thread-3线程生产了一个产品,产品ID cBd508