问题描述
开发短信服务平台,为多个系统提供短信服务。在发送短信时,经常会发生,短时间内短信发送太多,但是系统不能及时处理的情况。
为了解决该问题,引入生产者/消费者模式。
生产者/消费者模式简介
生产者既数据生产者、消费者既数据的处理者。
该模式是通过一个容器将生产者和消费者进行解耦,生产者生产出数据不直接调用消费者,而且将数据放到阻塞队列中;消费者也不直接从生产者手中拿数据,而是从阻塞队列中获取数据,从而实现生产者与消费者的解耦。
BlockingQueue用法简介
blockingQueue是阻塞队列接口主要有以下方法
add(Object o)是将对象添加到blockingQueue中,如果添加成功返回true,否则跑出异常;
offer(Object o)是将对象添加到blockingQueue中,如果成功则返回true,否则返回false;
put(Object o)是将对象添加到blockingQueue中,如果无空闲,则调用该方法的线程阻塞,直到有空闲;
poll(time)将排在首位的对象取出,若有则直接取出,否则就等定义的时间,超过该时间返回null;
take() 取出队列中排在首位的对象,若有直接取出,否则该线程阻塞,直到该队列中有对象取出;
代码示例
package test;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Test {
public static void main(String[] args) {
BlockingQueue queue = new LinkedBlockingQueue(30);
ProducerTest p1 = new ProducerTest(queue);
ProducerTest p2 = new ProducerTest(queue);
ProducerTest p3 = new ProducerTest(queue);
ConsumerTest c1 = new ConsumerTest(queue);
// ConsumerTest c2 = new ConsumerTest(queue);
new Thread(c1).start();
// new Thread(c2).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ExecutorService service = Executors.newFixedThreadPool(3);
service.execute(p1);
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
service.execute(p2);
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
service.execute(p3);
// service.shutdown();
}
}
class ProducerTest implements Runnable {
private BlockingQueue queue;
public ProducerTest(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
for (int i = 0; i < 100; i++) {
try {
queue.put(Thread.currentThread().getName() + "-" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ConsumerTest implements Runnable {
private BlockingQueue queue;
public ConsumerTest(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Object result = queue.take();
System.out.print(Thread.currentThread().getName() + " : "
+ result);
System.out.println("---长度:-- " + queue.size());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Test {
public static void main(String[] args) {
BlockingQueue queue = new LinkedBlockingQueue();
Producer p = new Producer(queue);
Consumer c = new Consumer(queue);
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(p);
service.execute(p);
service.execute(p);
service.execute(c);
}
}
class Producer implements Runnable {
private BlockingQueue queue;
public Producer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
queue.put(new Random().nextInt());
System.out.println(Thread.currentThread().getName() + " 放入: "
+ new Random().nextInt() + " 池中数量:" + queue.size());
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private BlockingQueue queue;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
Object result;
try {
while (true) {
result = queue.take();
Thread.sleep(3000);
System.out.println("<br>----------"
+ Thread.currentThread().getName() + "获取了: " + result);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}