有一个文件message.bat存储中商品变更信息,每一行存储一条信息,中间用逗号分隔,存储内容分别是:记录id,存储类型,商品编号,详细信息。
基础题:
用生产消费者模式实现对此文件的分析。
加分项:
1.如果有多个文件,形如:message.bat.seq ,seq取值范围 [0,n],现在要求用10个生产者线程读取文件信息,供消费者线程处理,保证不重复读取文件。
2.在某种条件下(自己设想某种情况),生产者线程,不再生产,这样生产者线程和消费者线程都结束。
题目本身并不难,不过可惜的是本人当时只做出一部分,有兴趣的朋友可以拿来练练手。下面给出自己回来做的结果,请批评指正。谢谢。
6 个解决方案
#1
ProductNotice:实体类
public class ProductNotice {
private String id;
private String type;
private String prodNum;
private String content;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getProdNum() {
return prodNum;
}
public void setProdNum(String prodNum) {
this.prodNum = prodNum;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String toString() {
return "id : " + id + ",type:" + type + ",prodNum:" + prodNum
+ ",content:" + content;
}
}
#2
ProducerThread(生产者线程)
public class ProducerThread extends Thread {
private LinkedBlockingQueue<ProductNotice> queue;
public ProducerThread(LinkedBlockingQueue queue) {
this.queue = queue;
}
public void run() {
int i=0;
while (true) {
BufferedReader reader = null;
try {
String fileName = "message.bat." + IdUtil.getId();
InputStream inStream = getClass().getResourceAsStream(
"/" + fileName);
while(inStream == null && i++< 10){
TimeUnit.SECONDS.sleep(1);
}
if(i >= 10){
ProductNotice pn = new ProductNotice();
pn.setId(null);
queue.put(pn);
System.out.println(Thread.currentThread().getName()+"发现不再有文件可供生产对象,即将退出");
break;
}
InputStreamReader inReader = new InputStreamReader(inStream);
reader = new BufferedReader(inReader);
System.out.println(Thread.currentThread().getName() + "开始读取文件:"
+ fileName);
String s = reader.readLine();
while (s != null) {
String[] strArr = s.split(",");
ProductNotice pn = new ProductNotice();
pn.setId(strArr[0]);
pn.setType(strArr[1]);
pn.setProdNum(strArr[2]);
pn.setContent(strArr[3]);
System.out.println(Thread.currentThread().getName()
+ ",生产了产品: " + pn);
queue.put(pn);
s = reader.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
#3
ConsumerThread 消费者线程
public class ConsumerThread extends Thread {
private LinkedBlockingQueue<ProductNotice> queue;
public ConsumerThread(LinkedBlockingQueue<ProductNotice> queue) {
this.queue = queue;
}
public void run() {
int i=0;
while (true) {
try {
ProductNotice pn = (ProductNotice)queue.take();
if(pn.getId() == null && ++i == 3){
System.out.println(Thread.currentThread().getName()+",发现生产者不再生产产品,自行退出");
break;
}else if(pn.getId() != null){
System.out.println(Thread.currentThread().getName()+",消费产品: "+pn);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
#4
不错的实例,谢谢分享
#5
没有线程池,文件也没有上锁处理。
2里面涉及的某种情况触发中断,可能是某个事件触发。可以加一个eventqueue,以及eventhandler之类。
2里面涉及的某种情况触发中断,可能是某个事件触发。可以加一个eventqueue,以及eventhandler之类。
#6
====
好代码演示下吗?谢谢。
#1
ProductNotice:实体类
public class ProductNotice {
private String id;
private String type;
private String prodNum;
private String content;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getProdNum() {
return prodNum;
}
public void setProdNum(String prodNum) {
this.prodNum = prodNum;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String toString() {
return "id : " + id + ",type:" + type + ",prodNum:" + prodNum
+ ",content:" + content;
}
}
#2
ProducerThread(生产者线程)
public class ProducerThread extends Thread {
private LinkedBlockingQueue<ProductNotice> queue;
public ProducerThread(LinkedBlockingQueue queue) {
this.queue = queue;
}
public void run() {
int i=0;
while (true) {
BufferedReader reader = null;
try {
String fileName = "message.bat." + IdUtil.getId();
InputStream inStream = getClass().getResourceAsStream(
"/" + fileName);
while(inStream == null && i++< 10){
TimeUnit.SECONDS.sleep(1);
}
if(i >= 10){
ProductNotice pn = new ProductNotice();
pn.setId(null);
queue.put(pn);
System.out.println(Thread.currentThread().getName()+"发现不再有文件可供生产对象,即将退出");
break;
}
InputStreamReader inReader = new InputStreamReader(inStream);
reader = new BufferedReader(inReader);
System.out.println(Thread.currentThread().getName() + "开始读取文件:"
+ fileName);
String s = reader.readLine();
while (s != null) {
String[] strArr = s.split(",");
ProductNotice pn = new ProductNotice();
pn.setId(strArr[0]);
pn.setType(strArr[1]);
pn.setProdNum(strArr[2]);
pn.setContent(strArr[3]);
System.out.println(Thread.currentThread().getName()
+ ",生产了产品: " + pn);
queue.put(pn);
s = reader.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
#3
ConsumerThread 消费者线程
public class ConsumerThread extends Thread {
private LinkedBlockingQueue<ProductNotice> queue;
public ConsumerThread(LinkedBlockingQueue<ProductNotice> queue) {
this.queue = queue;
}
public void run() {
int i=0;
while (true) {
try {
ProductNotice pn = (ProductNotice)queue.take();
if(pn.getId() == null && ++i == 3){
System.out.println(Thread.currentThread().getName()+",发现生产者不再生产产品,自行退出");
break;
}else if(pn.getId() != null){
System.out.println(Thread.currentThread().getName()+",消费产品: "+pn);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
#4
不错的实例,谢谢分享
#5
没有线程池,文件也没有上锁处理。
2里面涉及的某种情况触发中断,可能是某个事件触发。可以加一个eventqueue,以及eventhandler之类。
2里面涉及的某种情况触发中断,可能是某个事件触发。可以加一个eventqueue,以及eventhandler之类。
#6
====
好代码演示下吗?谢谢。