生产者和消费中模式在多线程中时经典中,我们下面通过这种方式来看看阻塞队列,锁机制以及最原始的方式的区别与联系:
[b][size=medium]对于通过阻塞队列:[/size][/b]
[b][size=medium]通过lock 锁机制[/size][/b]
[b][size=medium]通过notify 与wait方式[/size][/b]
上面三种中,第一种其实就是第二种的封转, basketQueue其实就相当于一个阻塞队列,我们在arrayListBlockingQueue中已经lock锁机制已经进行了封装。
可以看java的源代码(put方法),如下:
他在put方法中的实现第二种的实现原理是一样的。。所以阻塞队列实际就是对第二种basketQueue的封装。
[b][size=medium]对于通过阻塞队列:[/size][/b]
/**
*
*/
package com.chihonglu.ConsumerProducer.blockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Consumer implements Runnable{
BlockingQueue<Product> queue;
public Consumer(BlockingQueue<Product> queue) {
this.queue = queue;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000 * 2);
queue.take();
System.out.println(Thread.currentThread().getName() + "is taking the product");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.blockingQueue;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Producer implements Runnable{
private BlockingQueue<Product> queue;
public Producer(BlockingQueue<Product> queue) {
this.queue = queue;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10*100);
queue.put(new Product());
System.out.println(Thread.currentThread().getName() + " is putting the product");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.blockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Tester {
public static void main(String args[]) {
BlockingQueue<Product> queue = new ArrayBlockingQueue<Product>(5);
Consumer con1 = new Consumer(queue);
Consumer con2 = new Consumer(queue);
Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);
new Thread(con1).start();
new Thread(con2).start();
new Thread(producer1).start();
new Thread(producer2).start();
}
}
[b][size=medium]通过lock 锁机制[/size][/b]
/**
*
*/
package com.chihonglu.ConsumerProducer.lock;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author chihonglu
*
*/
public class BasketQueue {
private Lock lock = new ReentrantLock();
private Condition isEmpty = lock.newCondition();
private Condition isFull = lock.newCondition();
private int num = 0;
private List<Product> products = new LinkedList<Product>();
public void add(Product product) {
lock.lock();
try{
while(num == 10)
isFull.await();
num++;
products.add(product);
System.out.println("==========================");
System.out.println("the add string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
isEmpty.signal();
}catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void take() {
lock.lock();
try {
while(num==0) {
isEmpty.await();
}
num--;
products.remove(num);
isFull.signal();
System.out.println("==========================");
System.out.println("the take string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
} catch (Exception e) {
// TODO: handle exception
} finally {
lock.unlock();
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.lock;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Consumer implements Runnable{
BasketQueue queue;
public Consumer(BasketQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000 * 2);
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.lock;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Producer implements Runnable{
private BasketQueue queue;
public Producer(BasketQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10*100);
queue.add(new Product());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.lock;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Tester {
public static void main(String args[]) {
BasketQueue queue = new BasketQueue();
Consumer con1 = new Consumer(queue);
Consumer con2 = new Consumer(queue);
Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);
new Thread(con1).start();
new Thread(con2).start();
new Thread(producer1).start();
new Thread(producer2).start();
}
}
[b][size=medium]通过notify 与wait方式[/size][/b]
/**
*
*/
package com.chihonglu.ConsumerProducer.general;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author chihonglu
*
*/
public class BasketQueue {
private int num = 0;
private List<Product> products = new LinkedList<Product>();
public void add(Product product) {
try{
while(num == 10)
wait();
num++;
products.add(product);
System.out.println("==========================");
System.out.println("the add string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
notifyAll();
}catch (Exception e) {
e.printStackTrace();
}
}
public void take() {
try {
while(num==0) {
wait();
}
num--;
products.remove(num);
notifyAll();
System.out.println("==========================");
System.out.println("the take string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.general;
/**
* @author chihonglu
*
*/
public class Consumer implements Runnable{
BasketQueue queue;
public Consumer(BasketQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000 * 2);
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.general;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
/**
* @author chihonglu
*
*/
public class Producer implements Runnable{
private BasketQueue queue;
public Producer(BasketQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10*100);
queue.add(new Product());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
*
*/
package com.chihonglu.ConsumerProducer.general;
/**
* @author chihonglu
*
*/
public class Tester {
public static void main(String args[]) {
BasketQueue queue = new BasketQueue();
Consumer con1 = new Consumer(queue);
Consumer con2 = new Consumer(queue);
Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);
new Thread(con1).start();
new Thread(con2).start();
new Thread(producer1).start();
new Thread(producer2).start();
}
}
上面三种中,第一种其实就是第二种的封转, basketQueue其实就相当于一个阻塞队列,我们在arrayListBlockingQueue中已经lock锁机制已经进行了封装。
可以看java的源代码(put方法),如下:
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == items.length)
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
insert(e);
} finally {
lock.unlock();
}
}
他在put方法中的实现第二种的实现原理是一样的。。所以阻塞队列实际就是对第二种basketQueue的封装。