首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

多线程 有货色不明白

2012-12-17 
多线程 有东西不明白刚接触多线程 很多东西很晕,譬如网上这段代码,请教一下:其中有一段对这段代码的点评:“

多线程 有东西不明白
刚接触多线程 很多东西很晕,譬如网上这段代码,请教一下:

其中有一段对这段代码的点评:“出现了重复读取的问题,也肯定有重复覆盖的问题”
1.请问为什么会这这样?


2.因为Info的set方法和get方法都加上了synchronized ,所以当又一个线程调用了其中的一个方法时候(比如set),另外一个方法(比如get)也就被这个线程占用,不能被别的线程占用,这样理解对不?

3.不知道为什么会出现这样的运行结果,生产者线程不是已经占用Info的set和get ,然后在循环中一直把名字和年龄改来改去吗?消费者线程为什么还能输出每次生产者线程修改的结果?
这个程序的运行过程究竟是咋样的?谢谢前辈


class Info {
     
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public synchronized void set(String name, int age){
        this.name=name;
        try{
            Thread.sleep(100);
        }catch (Exception e) {
            e.printStackTrace();
        }
        this.age=age;
    }
     
    public synchronized void get(){
        try{
            Thread.sleep(100);
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(this.getName()+"<===>"+this.getAge());
    }
    private String name = "Rollen";
    private int age = 20;
}
 
/**
 * 生产者
 * */
class Producer implements Runnable {
    private Info info = null;
 
    Producer(Info info) {
        this.info = info;
    }
 
    public void run() {
        boolean flag = false;
        for (int i = 0; i < 25; ++i) {
            if (flag) {
                 
                this.info.set("Rollen", 20);
                flag = false;
            } else {
                this.info.set("ChunGe", 100);


                flag = true;
            }
        }
    }
}
 
/**
 * 消费者类
 * */
class Consumer implements Runnable {
    private Info info = null;
 
    public Consumer(Info info) {
        this.info = info;
    }
 
    public void run() {
        for (int i = 0; i < 25; ++i) {
            try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
            this.info.get();
        }
    }
}
 
/**
 * 测试类
 * */
public class hello {
    public static void main(String[] args) {
        Info info = new Info();
        Producer pro = new Producer(info);
        Consumer con = new Consumer(info);
        new Thread(pro).start();
        new Thread(con).start();
    }
}

运行结果:
Rollen<===>20

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

Rollen<===>20

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100

ChunGe<===>100




[最优解释]
 for (int i = 0; i < 25; ++i) {
            if (flag) {
                  
                this.info.set("Rollen", 20);
                flag = false;
            } else {
                this.info.set("ChunGe", 100);


                flag = true;
            }
        }

这段代码运行的太快了,瞬间就结束了,也就是说,他根本没有等消费者使用,就运行完毕了。你应该弄一个队列,或者堆栈,把生产的数据挨个放进去,消费者则挨个的获取。
有个Queue的类适合这个
[其他解释]
同楼上,按你的代码来看,估计要在
 for (int i = 0; i < 25; ++i) {
             if (flag) {
                   
                 this.info.set("Rollen", 20);
                 flag = false;
             } else {
                 this.info.set("ChunGe", 100);
                 flag = true;
             }
         }
里面加一个Thread.sleep(100)才能达到你的目的
[其他解释]


 for (int i = 0; i < 25; ++i) {            if (flag) {                                  this.info.set("Rollen", 20);                flag = false;            } else {                this.info.set("ChunGe", 100);                flag = true;            }        }

这个锁,只有你调用
this.info.set("Rollen", 20);  
和 this.info.set("ChunGe", 100);
的时候会锁住,这两行执行完了,锁就放开了
除非你是synchronized把整段括起来

[其他解释]
提供一多线程例子


public class Yi_Hong_Courtyard {

public static void main(String[] args) {
// TODO Auto-generated method stub
Yi_Hong_Courtyard yunxing = new Yi_Hong_Courtyard();

}


Yi_Hong_Courtyard(){

Procuress procuress = new Procuress();

Miss miss = new Miss(procuress);
Piao_Guest guest = new Piao_Guest(procuress);

Thread t_miss = new Thread(miss);
Thread t_guest = new Thread(guest);

Produce_Business();//内容介绍{函数在29--31行}

t_miss.start();
t_guest.start();

}

public void Produce_Business(){
System.out.println("欢迎光临大日本怡红院-----祝您玩的愉快(xi wang nin zai e gao zhong xue hui duo xian cheng)");


}
}

//小姐...给钱就干
class Miss implements Runnable{

Procuress procuress;

public Miss(Procuress procuress){
this.procuress = procuress;
}

@Override
public void run() {
// TODO Auto-generated method stub
int i = 1;
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(i == 1){
try {
procuress.fenpen_miss("苍井空","500日元");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
try {
procuress.fenpen_miss("甜心花子", "800日元");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
i = (i+1) % 2;
}
}

}

//嫖客...花钱就嫖
class Piao_Guest implements Runnable{

Procuress procuress;

public Piao_Guest(Procuress procuress){
this.procuress = procuress;
}

@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
procuress.make_love();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}

//老鸨...统一管理小姐内部工作
class Procuress{

private String miss = null;
private String price = null;
private boolean jie_Guest = true;

public synchronized void fenpen_miss(String miss,String price) throws InterruptedException{
if(!jie_Guest)
wait();//等待
this.miss = miss;
this.price = price;
jie_Guest = false;
notify();//叫醒
}

public synchronized void make_love() throws InterruptedException{
if(jie_Guest)
wait();//等待
System.out.println("接客小姐:"+miss);
System.out.println("接客价格:"+price);
System.out.println("  "+"  "+"  "+"  "+"  "+"  "+"  "+"  "+"  "+"  "+miss+"工作完事"+"准备接客... ...");
System.out.println("****************************************");
jie_Guest = true;
notify();//叫醒
}
}


[其他解释]
引用:
同楼上,按你的代码来看,估计要在
 for (int i = 0; i < 25; ++i) {
             if (flag) {
                   
                 this.info.set("Rollen", 20);
                 flag = false;


          ……



加上了Thread.sleep(100)之后输出结果会有
Rollen<===>20
ChunGe<===>100
间隔出现

但为什么生产者线程占用了set和get方法后,消费者线程还能调用get方法,这两个方法不是被synchronized锁住了吗?
[其他解释]
引用:
for (int i = 0; i < 25; ++i) {
            if (flag) {
                  
                this.info.set("Rollen", 20);
                flag = false;
            } else {
          ……


这里消费者为什么还能调用get方法?不是被生产者锁住了吗?
[其他解释]
 为什么Info参数可以共用?
[其他解释]
三楼人才啊。
[其他解释]
引用:
Java code?12 for (int i = 0; i < 25; ++i) {            if (flag) {                                  this.info.set("Rollen", 20);                flag = false;            } else {          ……


明白了 是在调用set方法时候才锁住,但是一调用完的时候,锁就释放了,另一个线程可以调用这个方法了!

热点排行