Java 使用阻塞队列的生产者-消费者
我有一个使用阻塞的生产者/消费者实现,我这样启动它们Java 使用阻塞队列的生产者-消费者,java,producer-consumer,blockingqueue,Java,Producer Consumer,Blockingqueue,我有一个使用阻塞的生产者/消费者实现,我这样启动它们 BlockingQueue<Object> myQueue1 = new LinkedBlockingQueue<Object>(); new Thread(new SmsInProducer(myQueue1, 100)).start(); for (int i = 0; i < 100; i++ ) { new Thread(new SmsInConsumer(myQueue1)).start();
BlockingQueue<Object> myQueue1 = new LinkedBlockingQueue<Object>();
new Thread(new SmsInProducer(myQueue1, 100)).start();
for (int i = 0; i < 100; i++ ) {
new Thread(new SmsInConsumer(myQueue1)).start();
}
public class SmsInProducer implements Runnable {
protected BlockingQueue queue;
protected int MAX_RECORDS = 5000;
@SuppressWarnings("rawtypes")
public SmsInProducer(BlockingQueue theQueue, int maxRecord) {
this.queue = theQueue;
this.MAX_RECORDS = maxRecord;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
int totalRecords = MAX_RECORDS - queue.size();
if (totalRecords > 0) {
List<Map> tList = Sql.updateTRECEIVE();
if (tList != null && !tList.isEmpty()) {
queue.addAll(tList);
}
}
// wait for 1 second
try { Thread.sleep(Parameter.replyWaitTime * 1000); } catch(Exception e) {}
}
}
public class SmsInConsumer implements Runnable {
@SuppressWarnings("rawtypes")
protected BlockingQueue queue;
@SuppressWarnings("rawtypes")
public SmsInConsumer(BlockingQueue theQueue) {
this.queue = theQueue;
}
@SuppressWarnings("rawtypes")
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Object obj = queue.take();
Map map = (Map) obj;
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception e) {
e.printStackTrace();
} finally {
try { Thread.sleep(Parameter.replyWaitTime * 1000); } catch(Exception e){}
}
}
}
但是过了一段时间,它会变得非常慢,我还能保持它非常快吗?删除消费者中的睡眠,对queue.take()的调用将阻塞线程,直到有对象可用,所以不需要睡眠 但是,由于它的启动速度很快,而且随着时间的推移会变慢,所以请尝试优化您的制作人。 尝试在队列中使用更多元素,优化Sql.UpdateReceive();并移除睡眠。
导入java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author sakshi
*/
public class BlockingqueueDemo {
static BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
static class Producer extends Thread {
BlockingQueue queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("produce" + i);
try {
queue.put(i);
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(BlockingqueueDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
static class Consumer extends Thread {
BlockingQueue queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("consume" + queue.take());
} catch (InterruptedException ex) {
Logger.getLogger(BlockingqueueDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String[] args) {
Producer produce = new Producer(queue);
Consumer consume = new Consumer(queue);
produce.start();
consume.start();
}
}
output:
produce0
consume0
produce1
consume1
produce2
consume2
produce3
consume3
produce4
consume4
produce5
consume5
produce6
consume6
produce7
consume7
produce8
consume8
produce9
consume9
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.LinkedBlockingQueue;
导入java.util.logging.Level;
导入java.util.logging.Logger;
/*
*要更改此许可证标题,请在“项目属性”中选择“许可证标题”。
*要更改此模板文件,请选择工具|模板
*然后在编辑器中打开模板。
*/
/**
*
*@作者sakshi
*/
公共类阻塞队列演示{
静态BlockingQueue=新建LinkedBlockingQueue();
静态类生成器扩展线程{
阻塞队列;
公共生产者(封锁队列){
this.queue=队列;
}
公开募捐{
对于(int i=0;i<10;i++){
系统输出打印项次(“生产”+i);
试一试{
排队。付诸表决(i);
《睡眠》(2000年);
}捕获(中断异常例外){
Logger.getLogger(BlockingqueueDemo.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
}
静态类使用者扩展线程{
阻塞队列;
公共消费者(封锁队列){
this.queue=队列;
}
公开募捐{
对于(int i=0;i<10;i++){
试一试{
System.out.println(“消费”+队列.take());
}捕获(中断异常例外){
Logger.getLogger(BlockingqueueDemo.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
}
公共静态void main(字符串[]args){
生产商生产=新生产商(队列);
消费者消费=新消费者(队列);
product.start();
consume.start();
}
}
输出:
生产
消费0
产品1
消费1
产品2
消费2
生产3
消费3
生产4
消费4
生产5
消费5
生产
消费6
生产7
消费7
生产8
消费8
生产9
消费9
您尝试过探查器吗?哪个部分变慢了?请删除对Thread.sleep()
的调用?Thread.sleep()已为0,因此它不会等待。我将在您排队和线程池时使用内置的ExecutorService。我怀疑您的主要延迟出现在Sql.UpdateReceive()中,或者您每秒会收到100条记录,因为队列很快就会填满和清空。测试这一点最简单的方法是将睡眠延迟恢复到10ms,然后看看是否更快。顺便说一句:对于CPU受限的任务,线程的最佳数量可以是您拥有的空闲CPU数量,例如,它可以是1到10。因为Java API说阻塞队列单元素简单操作是线程安全的,所以我开始怀疑这是否是机器问题。你的机器有多少芯?如果在每个循环结束时放入Thread.yeild()调用,性能是否稳定?我应该在队列中使用哪些元素?需要哪些元素。请记住,创建大型对象会降低制作者的性能。并使用泛型来摆脱@SuppressWarnings(“rawtypes”),或许可以提高一些速度(但我不知道这是否真的重要)