线程--生产者与消费者的案例
一,本章目标
①加深线程同步操作的理解
②了解object类中对线程的支持方法
二,具体内容
先定义一个信息的表示类,生产者和消费者同时占有信息类,这样就把三者联系起来。
写一个生产者类:
生产者每次生产50种信息,生产完50次之后改变信息的内容,为了更好的看出效果,加入延迟操作。
一个消费者类:
通过测试代码来发现程序的问题
程序结果出现了问题:信息不对应,重复取了。之所以出现内容不对应的问题,是因为中间加入的延迟操作,这个时候就可以使用同步操作。
package 线程操作范例;
public class Info {
private String name = "李兴华";
private String content = "java讲师";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public synchronized void set(String name,String content){
this.setName(name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.setContent(content);
}
public synchronized void get(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(this.getName() + " -->"
+this.getContent());
}
}
class Producer implements Runnable{
private Info info = null;
public Producer(Info info){
this.info = info;
}
public void run() {
// TODO Auto-generated method stub
boolean flag = false;
for(int i=0;i<50;i++){
if(flag){
this.info.set("李兴华","java讲师");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = false;
}else{
this.info.set("mldn","www.mldnjava.cn");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = true;
}
}
}
}
class Consumer implements Runnable{
private Info info = null;
public Consumer(Info info){
this.info = info;
}
public void run() {
// TODO Auto-generated method stub
this.info.get();
}
}
以上的代码解决了数据的完整性问题,但是依然存在重复取的问题,需要使用Object类的支持,所以优化代码如下:
有2个唤醒方法。
直接修改Info类,增加等待与唤醒操作。
此时,才真正完成了生产者与消费者的完成操作。
总结,在本程序中,注意两下两点问题:生产者要不断生产,但是不能生产错误的信息和重复的信息
消费者要不断的取走,但是不能重复取走
object类中对线程的支持:
等待与唤醒方法