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();
}