一、修改 Info 类
如果要为操作加入同步,可以通过定义同步方法的方式完成,即将设置名称和姓名定义成一个同步方法
class Info {
private String name = "JAVA";
private String content = "LANGUAGE";
public synchronized void set(String name,String content){//设置信息名称及内容
this.setName(name);//设置信息名称
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
this.setContent(content);//设置信息内容
}
public synchronized void get(){//取得信息内容
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getName() + " --> " + this.getContent());//输出信息
}
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;
}
}
class Producer implements Runnable{//定义生产者线程
private Info info = null;//保存 Info 引用
public Producer(Info info){//通过构造方法设置 info 属性内容
this.info = info;//为 info 属性初始化
}
public void run(){//覆写 run()方法
boolean flag = false;//定义标记位
for(int i=0;i<10;i++){
if (flag){//如果为 TRUE,则设置第一个信息
this.info.set("Java_1","Language_1");
flag = false;//修改标记位
}else {//如果为false,则设置第2 个信息
this.info.set("Java_2","Language_2");
flag = true;//修改标记位
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
三、修改消费者
class Consumer implements Runnable{
private Info info = null;
public Consumer(Info info){
this.info = info;//通过构造方法设置 info 属性,为 info 属性初始化
}
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(20);
}catch (InterruptedException e){
e.printStackTrace();
}
this.info.get();//取出信息
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
四、测试
public class ThreadCase {
public static void main(String[] args) {
Info i = new Info();
Producer pro = new Producer(i);//实例化生产者,传递 Info 引用
Consumer con = new Consumer(i);//实例化消费者,传递 Info 引用
new Thread(pro).start();//启动生产者线程
new Thread(con).start();//启动消费者线程
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
此时信息错乱问题已经解决,但是依然存在重复读取的问题,既然有重复读取,则肯定会有重复设置的问题