在公司做培训时用到,顺便在这里做个总结。
1.生产者消费者模式
某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。
2.future模式
从java 5开始,Java提供了Callable接口,该接口是Runnable接口的增强版,Callable接口提供了一个call()方法,可以作为线程执行体,但call()方法比run()方法的功能更强大。
call()方法可以有返回值,call()方法可以声明抛出异常。
1.生产者消费者模式
某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。
/**
*
* 类功能描述:数据对象
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-2 上午11:01:53
*/
public class MyData {
private final long intData;
public MyData(long d){
intData = d;
}
@Override
public String toString(){
return " MyData:"+intData;
}
}
import java.util.concurrent.BlockingQueue;
public abstract class AbstractPC implements Runnable {
protected BlockingQueue<MyData> queue;
protected volatile boolean isRunning = true;
public void stop() {
isRunning = false;
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
* 类功能描述:生产者
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-2 上午11:02:13
*/
public class Producer extends AbstractPC{
private static AtomicInteger count = new AtomicInteger(0);
private static final int SLEEP_TIME = 3000;
public Producer(BlockingQueue<MyData> queue) {
this.queue = queue;
}
public void run() {
System.out.println("Producer:"+Thread.currentThread().getName()+" start");
try {
while (isRunning) {
Thread.sleep(SLEEP_TIME);
MyData data = new MyData(count.incrementAndGet());
queue.put(data);
System.out.println(Thread.currentThread().getName()+" produce:" + data);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.concurrent.BlockingQueue;
/**
*
* 类功能描述:消费者
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-2 上午11:02:22
*/
public class Consumer extends AbstractPC{
private static final int SLEEP_TIME = 3000;
public Consumer(BlockingQueue<MyData> queue) {
this.queue = queue;
}
public void run() {
System.out.println("Consumer:"+Thread.currentThread().getName()+" start");
try {
while(isRunning){
Thread.sleep(SLEEP_TIME);
MyData data = queue.take();
if (null != data) {
System.out.println(Thread.currentThread().getName()+" consume:"+data);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
*
* 类功能描述:完全利用并发包的特性,最优的实现方式。
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-3-28 下午01:10:51
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<MyData> queue = new LinkedBlockingQueue<MyData>(10);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
ExecutorService service = Executors.newCachedThreadPool();
service.execute(producer);
service.execute(producer);
service.execute(producer);
service.execute(consumer);
Thread.sleep(10000);
producer.stop();
System.out.println("producer stop!");
Thread.sleep(10000);
System.out.println("consumer stop!");
consumer.stop();
service.shutdown();
}
}
//下面是链式阻塞队列的内部简单实现
public interface BlockingQueue<T> {
/**
*
* @function:插入元素
* @param e
* @throws InterruptedException
* @author: mengqingyu 2013-4-2 上午10:39:19
*/
void put(T e) throws InterruptedException;
/**
*
* @function:取出元素
* @return
* @throws InterruptedException
* @author: mengqingyu 2013-4-2 上午10:39:16
*/
T take() throws InterruptedException;
}
/**
*
* 类功能描述:阻塞队列的内部实现
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp @param <T> $
* Create: 2013-4-2 上午11:04:29
*/
public class LinkedBlockingQueue<T> implements BlockingQueue<T>{
//链表容量
private final int capacity;
//计数器
private final AtomicInteger count = new AtomicInteger(0);
//队列头引用
private transient Node<T> head;
//队列尾引用
private transient Node<T> last;
//锁
private Lock lock = new ReentrantLock();
//生产者条件锁
private Condition condition_producer = lock.newCondition();
//消费者条件锁
private Condition condition_consumer = lock.newCondition();
//链表内部类
static class Node<T> {
volatile T item; //数据区
Node<T> next; //后继结点
Node(T x) { item = x; }
}
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<T>(null);
}
@Override
public void put(T t) throws InterruptedException {
if (t == null) throw new NullPointerException();
lock.lock();
try {
while (count.get() == capacity) //当容量满时候等待,用循环的目的是每次被唤醒都需要重新检查是否满足条件。
condition_producer.await();
insert(t);//插入元素
System.out.println(Thread.currentThread().getName()+" push:"+(capacity-1)+t);
count.getAndIncrement();//计数器加1
condition_consumer.signalAll();
} catch (InterruptedException e) {
condition_consumer.signalAll();
e.printStackTrace();
}
finally {
lock.unlock();
}
}
/**
*
* @function:插入元素
* @param x
* @author: mengqingyu 2013-4-2 上午10:36:52
*/
private void insert(T x) {
last = last.next = new Node<T>(x);
}
@Override
public T take() throws InterruptedException {
T x = null;
lock.lock();
try{
while (count.get() == 0)
condition_consumer.await();
x = extract();
System.out.println(Thread.currentThread().getName()+" pop:"+capacity+x);
count.getAndDecrement();
condition_producer.signalAll();
} catch (InterruptedException e) {
condition_producer.signalAll();
e.printStackTrace();
}
finally {
lock.unlock();
}
return x;
}
/**
*
* @function:取出元素
* @return
* @author: mengqingyu 2013-4-2 上午10:36:31
*/
private T extract() {
Node<T> first = head.next;
head = first;
T x = first.item;
first.item = null;
return x;
}
}
2.future模式
从java 5开始,Java提供了Callable接口,该接口是Runnable接口的增强版,Callable接口提供了一个call()方法,可以作为线程执行体,但call()方法比run()方法的功能更强大。
call()方法可以有返回值,call()方法可以声明抛出异常。
import java.util.concurrent.Callable;
/**
*
* 类功能描述:实现Callable接口重写call方法,支持多线程下抛出异常,主线程阻塞等待子线程的返回值。
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-2 上午11:06:47
*/
public class DataService implements Callable<String> {
private String param;
private static final int SLEEP_TIME = 1000;
public DataService(String param){
this.param = param;
}
@Override
public String call() throws InterruptedException{
StringBuffer sb=new StringBuffer();
for (int i = 0; i < 5; i++) {
sb.append(param);
System.out.println("Chlid Thread wait 1 second...");
Thread.sleep(SLEEP_TIME);
}
return sb.toString();
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
/**
*
* 类功能描述:jdk实现,可以直接使用
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-3-28 下午01:11:43
*/
public class Main {
public static void main(String[] args) {
FutureTask<String> future = new FutureTask<String>(new DataService("Hello "));
ExecutorService executor = Executors.newFixedThreadPool(1);
try {
executor.execute(future);
System.out.println("Main Thread wait 2 second...");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("future.get() before");
try {
System.out.println("result:" + future.get());//线程阻塞,直到取到返回值
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
}
}
//下面是future的内部实现
public interface Callable<T> {
T call() throws Exception;;
}
public interface Future<T> {
T get()throws Exception;
}
/**
*
* 类功能描述:future内部实现,包含获取结果集和异常信息的方法
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp @param <T> $
* Create: 2013-4-2 上午11:08:52
*/
public class FutureTask<T> implements Future<T>,Runnable {
private T data;
private Exception exception;
private Callable<T> callable;
private boolean isReady = false;
public FutureTask(Callable<T> callable) {
this.callable = callable;
}
public synchronized T get() throws Exception {
while (!isReady) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (exception != null)
throw exception;
return data;
}
@Override
public synchronized void run() {
if (isReady) {
return;
}
try {
data = callable.call();
} catch (Exception e) {
exception = e;
}
isReady = true;
notifyAll();
}
}