producer consumer

本文介绍了一个基于Java实现的生产者消费者模式示例,利用多线程技术,通过一个LinkedBlockingQueue作为中间数据队列,实现了从数据库读取数据并进行处理(评分),然后再将处理后的数据写回数据库的过程。该示例包括了生产者线程如何获取数据并进行评分,以及消费者线程如何消费这些数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mark......

public class ProducerConsumer {
		private LinkedBlockingQueue<DBObject> _queue = new LinkedBlockingQueue<DBObject>(1000);
		private final Lock _lock = new ReentrantLock();
		private DBCollection _coll = null;
		private volatile DBCursor _cur = null;
		private int _producers;
		private int _customers;
		private volatile boolean _producerRunning = false;
		private volatile boolean _finishedConsume = false;
		private AtomicInteger _finishedProducers = new AtomicInteger(0);
		private AnswerScorers scorers = new AnswerScorers("", -5000, 10000);

		public ProducerConsumer(DBCollection coll, int producers, int customers) {
			this._coll = coll;
			this._producers = producers;
			this._customers = customers;
		}

		/**
		 * 另外一种串行获取数据的方式。
		 * @return
		 */
		private synchronized DBObject next() {
			if (!_cur.hasNext()) {
				return null;
			}
			return _cur.next();
		}

		public void start() {
			this._cur = _coll.find();
			_producerRunning = true;
			_finishedProducers.set(0);
			for (int i = 0; i < _producers; i++) {
				new Producer().start();
			}
			for (int i = 0; i < _customers; i++) {
				new Consumer().start();
			}
			try {
				while (!_finishedConsume) {
					Thread.sleep(1000);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		/**
		 * 生产一条数据,放在数据队列。
		 * @author xiuleili
		 *
		 */
		class Producer extends Thread {
			public void run() {
				int count = 0;
				
				try {
					while (true) {
						// DBObject dbo = next();
						// this code has the same effect with next lines:
						DBObject dbo = null;
						_lock.lock();
						if (_cur.hasNext()) {
							dbo = _cur.next();
						}						
						_lock.unlock();

						if(dbo == null){
							break;
						}
						
						count++;
						AnswerNLP answer = buildAnswerNlpFromDBO(dbo);
						int score = scorers.score(answer);
						dbo.put("score", new Integer(score));
						_queue.put(dbo);
					}
				} catch (Exception e) {
				} finally {
					System.out.println(Thread.currentThread().getName() + " total produced " + count);
					if (_finishedProducers.addAndGet(1) == _producers) {
						_producerRunning = false;
					}
				}

			}
		}

		/**
		 * 消费一条数据,写入数据库。
		 * @author xiuleili
		 *
		 */
		class Consumer extends Thread {
			public void run() {
				int count = 0;
				while (_producerRunning || !_queue.isEmpty()) {
					try {
						// 取出一个对象
						DBObject dbo = _queue.poll(300, TimeUnit.MILLISECONDS);
						if (dbo == null) {
							continue;
						}

						DBObject query = new BasicDBObject("answerId", dbo.get("answerId"));
						DBObject update = new BasicDBObject("$set", new BasicDBObject("score", dbo.get("score")));

						_coll.update(query, update);
						count++;

					} catch (InterruptedException e) {
						System.out.println("producer is interrupted!");
					}
				}

				System.out.println(Thread.currentThread().getName() + " total consumed " + count);
				_finishedConsume = true;
			}
		}

	}

	/**
	 * 使用多线程的方法进行操作。多个生产者进行分析,多个个消费者进行数据库写。
	 */
	public static void scoreAnswersThreads() {
		DBCollection coll = MongoDriver.getCollection("mongodb://10.13.95.60/test.answerNLP");
		new DBDataManage().new ProducerConsumer(coll, 10, 2).start();
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值