A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 曾祥旭 中级黑马   /  2013-3-27 07:39  /  1903 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 曾祥旭 于 2013-3-27 11:31 编辑

class Resource{
        String name;
        String sex;
}
class Input implements Runnable{
        Resource r;
        Input(Resource r){
                this.r=r;
        }
        public void run(){
                int x=0;
                while(true){
                        synchronized(Resource.class){
                                if(x==0){
                                        r.name="mike";
                                        r.sex="man";
                                }
                                else{
                                    r.name="丽丽";
                                    r.sex="女女女女女女";
                                }
                        }
                        x=(x+1)%2;
                }
        }
}
class Outer implements Runnable{
        Resource r;
        Outer(Resource r){
                this.r=r;
        }
        public void run(){
                while(true){
                        synchronized(Resource.class){//虽然输入线程同步,但是输出的线程也是需要同步的
                        System.out.println(r.name+"-->"+r.sex);
                        }
                }
        }
}
public class Test{
        public static void main(String[] args){
                //创建资源
                Resource r=new Resource();
                //创建任务
                Input in=new Input(r);
                Outer out=new Outer(r);
                //创建线程,执行路径。
                Thread t1=new Thread(in);
                Thread t2=new Thread(out);
                //开启线程
                t1.start();
                t2.start();
        }
}

在上述代码中,产生的结果有成片出现相同的name与sex的情况,我知道当输入时候,Input抢到执行权,它可以成片的往里面输入数据,但是,为什么可以取出成片的数据结果呢?之前输入的数据不是被后来输入的数据进行覆盖了吗?如果覆盖,就不能取出成片出现的结果啊,如果没有覆盖,那么存储的数据的位置在哪,不过,给我的感觉是覆盖了之前输入的数据的。求解?(本人电脑是单核,那么CPU在快速切换的时候,Input抢到执行权,Output也就不能输出,因此,排除了t1与t2线程同时执行的情况,那么会不会是这样,t1线程执行的是mike这组数据,t2线程执行的是输出,t1与t2线程在不停的输入与输出同一组数据?)有没有覆盖这种情况呢?

点评

如果你的问题已经得到解决,请及时将主题改为[已解决],如果还有问题请继续追问,谢谢!  发表于 2013-3-27 10:49

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

4 个回复

倒序浏览
哈哈。没学到那呢,不好意思奥
回复 使用道具 举报
楼主你好

希望可以帮到你

问题:为什么会出现一大片一大片的  男那女女 这样的情况?
分析:
当某一个线程获得执行权的时候,并不会只输出1次,CPU是随机切换的,所以只有在CPU在某一个时刻切换到另一个线程时候,
才会终止当前,而后继续大片片的执行另一个线程。总体来说就是线程并发的抢占性和CPU处理数据的随机性共同造成的这样的局面。
解决:
1:给资源类加个标记。类似与开关,真代表有货,假代表没货。

2:input类,同步代码块里,判断:
若有货(标记为真)则不拉煤进去(给我在外面等着wait()),
若没货,(标记为假),兄弟们给我拉煤进去(往里存数据),
存完后记得记录下,说明里头有货了(flag=true),说明里头有货了,哥们儿不要再往里存了。
3:output类,同步代码块里:判断,
若没货,哥们儿在外面等(flag=非真),货都没有咱取不了啊。
若有货,哥们就进去取,(flag=非假), 有货哥们儿才能进仓库取啊,但是取完后记录下,取完后里面没货了(flag=false) 哥们儿些别往仓库里冲了。

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

回复 使用道具 举报
看了半天,才看懂,下次建议用代码粘贴,不要直接粘贴呵呵。下面是我的解释,你看看是不是这样的:
首先,你这个程序只有个2个线程
                t1.start();
                t2.start();
对吧?
ti是输入线程,t2是输出线程。虽然同时运行,但是t1的输入线程已经锁住了,他的输入时,不可能出现mike和女这种情况的。所以输入的结果一定是mike。。man,丽丽和女女。
t2虽然锁住了,但是因为t1输入的时候不会出现抢线程的情况,t2输出是一片一片的。

至于你说的为什么覆盖老师貌似也没多讲啊。我的理解是只要执行多线程,运行start()线程就会一直执行run方法的,每执行一个run方法,就建立一个对象,这个对象应该是在堆内存中new run()吧?不知道对不对,个人感觉是这样~~~~
有疑问回复一下~

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

回复 使用道具 举报
因为Input和Outer的同步代码块使用的是同一个锁,所以某个时间只能执行他们两个中的一个,也就是输入的时候不能同时在输出。
当t1线程抢到执行权后一直在进行着输入,输入mike man和丽丽 女交替进行,并将值保存在共享数据r 的neme和sex里,新值会覆盖原来的值。
当某一时刻t2抢到执行权,就会一直打印最后保存在r里面的name和sex,所以就会成片的打印同样的结果。

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马