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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

package thread.conAndpro;

public class Synchronized_Test {
        public static void main(String[] args) {
                Resouse_1 r=new Resouse_1();
                Producer_1 p=new Producer_1(r);
                Consumer_1 c=new Consumer_1(r);
               
                new Thread(p).start();
                new Thread(p).start();
                new Thread(c).start();
                new Thread(c).start();
        }
}

class Resouse_1{
        private int count;
        Boolean flag=false;
       
        public synchronized void produce(String name){
                while(flag)
                        try {
                                this.wait();;
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                System.out.println(name+"生产了"+(++count));
                flag=!flag;
//我想问这地方如果消费者的两个线程都在wait()的话,生产者的一个线程将所有的线程都唤醒,是不是会造成
//消费者的两个线程都在运行,消费者的两个线程都判断标记为false,所以都往下执行,不就导致共享数据错误??、
                this.notifyAll();
        }
       
        public synchronized void consume(String name){
                while(!flag)
                        try {
                                this.wait();
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                System.out.println(name+"消费了。。。。。。"+count);
                flag=!flag;
                this.notifyAll();
        }
}

class Producer_1 implements Runnable{
        private Resouse_1 r;
       
        Producer_1(Resouse_1 r){
                this.r=r;
        }
       
        public void run(){
                while(true)
                        r.produce(Thread.currentThread().getName());
        }
}

class Consumer_1 implements Runnable{
        private Resouse_1 r;
       
        Consumer_1(Resouse_1 r){
                this.r=r;
        }
       
        public void run(){
                while(true)
                        r.consume(Thread.currentThread().getName());
        }
}

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 神马都是浮云

查看全部评分

24 个回复

倒序浏览
你说的情况是if来判断flag才会发生的 但是你这里用while来判断的话就不会出现,一旦线程被唤醒后就会继续进到while里面来判断
回复 使用道具 举报
ixiangfeng 发表于 2014-1-11 15:26
你说的情况是if来判断flag才会发生的 但是你这里用while来判断的话就不会出现,一旦线程被唤醒后就会继续进 ...

我知道是while啊,我说的就死while。你看我问的:我想问这地方如果消费者的两个线程都在wait()的话,生产者的一个线程将所有的线程都唤醒,是不是会造成消费者的两个线程都在运行,消费者的两个线程都判断标记为false,所以都不会冻结,都往下执行,不就导致共享数据错误??、
回复 使用道具 举报
synchronized 你这个关键字是用来干啥的? 怎么能两个消费者同时执行呢
明显是一个进去执行完方法里面所有的代码 另外一个消费者才进来判断啊
回复 使用道具 举报
潜伏 发表于 2014-1-12 00:54
我知道是while啊,我说的就死while。你看我问的:我想问这地方如果消费者的两个线程都在wait()的话,生 ...

CPU不可能同时运行两个线程的,两个消费者的线程都被唤醒了就是说他们两个线程都有执行资格,但不一定有执行权,而假设两个消费者中的一个抢到CPU执行权的话,那它就会去判断一下flag,这时不符合wait的条件,它就执行下面的代码,会改变flag,这时即使另外一个线程抢到执行权也会到while里面判断flag,而不是直接执行下面的代码
回复 使用道具 举报
双核cpu是可以同时运行两个线程的
回复 使用道具 举报
潜伏 中级黑马 2014-1-13 00:27:24
7#
75100313 发表于 2014-1-12 08:30
synchronized 你这个关键字是用来干啥的? 怎么能两个消费者同时执行呢
明显是一个进去执行完方法里面所有 ...

不是的,当一个消费线程拿到锁后,如果通过判断语句满足的话就会wait,同时也会释放锁,消费的另一线程也可能拿到锁,进而通过判断语句又wait了,锁释放,此时生产线程拿到锁,就执行生产语句。是不是???、呵呵呵
回复 使用道具 举报
潜伏 中级黑马 2014-1-13 00:31:45
8#
ixiangfeng 发表于 2014-1-12 12:17
CPU不可能同时运行两个线程的,两个消费者的线程都被唤醒了就是说他们两个线程都有执行资格,但不一定有 ...

当然连个消费者都会判断标记,不过如果一个消费线程判断满足后,执行while后面的代码,而没有执行到打印代码或者改变标记的代码就放弃了执行权,另外一线程恰好获得执行权,判断标记也满足不就业往下执行吗???????????????????????????????????????
回复 使用道具 举报
潜伏 发表于 2014-1-13 00:31
当然连个消费者都会判断标记,不过如果一个消费线程判断满足后,执行while后面的代码,而没有执行到打印 ...

你忘了synchronized了吗 一个线程在执行代码时另外一个线程即使获取到了CPU的执行权也是进不去的 像你说的如果一个线程进去了,然后不符合while的条件,那它就执行while下面的代码,而即使它还没有执行到打印或者改变标记的代码时就放弃了执行权,另外一线程获得了执行权也是进不去的,因为被synchronized锁住了,还有不知道你是不是对wait不太清楚,再给你说一下,synchronized是同步,锁上了就不能有两条线程在里面执行代码,而wait方法是会释放锁的,也就是说假如有一线程进去了synchronized方法里面然后遇到了wait方法,那这线程就会释放锁,相当于里面没有线程在执行,另外一个线程才可以进去

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 赞一个!

查看全部评分

回复 使用道具 举报
75100313 发表于 2014-1-12 08:30
synchronized 你这个关键字是用来干啥的? 怎么能两个消费者同时执行呢
明显是一个进去执行完方法里面所有 ...

wait方法会释放锁的,而这里synchronized方法里面也没有同时两个线程在执行,因为一个线程进去遇到wait方法后就会等待,然后释放锁,这时相当于里面没有线程,另外一个线程是可以进去的
回复 使用道具 举报
本帖最后由 75100313 于 2014-1-14 08:56 编辑
ixiangfeng 发表于 2014-1-13 11:30
wait方法会释放锁的,而这里synchronized方法里面也没有同时两个线程在执行,因为一个线程进去遇到wait方 ...
关键就是那个while()!
回复 使用道具 举报
75100313 发表于 2014-1-14 08:28
关键就是那个while()!

线程进去同步函数里面 如果等待了 然后被唤醒了,它就会重新判断while循环的条件,你看一下我上面的解释
回复 使用道具 举报
ixiangfeng 发表于 2014-1-14 10:09
线程进去同步函数里面 如果等待了 然后被唤醒了,它就会重新判断while循环的条件,你看一下我上面的解释 ...

老大 我有点晕了  那为什么前面要加synchronized 这个啊 不是释放锁?
还不如不加这个  我晕了  这个问题我都觉得很白痴  求解答啊
回复 使用道具 举报
75100313 发表于 2014-1-14 10:45
老大 我有点晕了  那为什么前面要加synchronized 这个啊 不是释放锁?
还不如不加这个  我晕了  这个问题 ...

加了synchronized在这个函数上是同步函数,简单地说同步函数的作用是加锁,使得两条线程同时执行函数里面的代码这种情况不会发生,不是释放锁,建议你还是回去看一下毕老师12天1-5的视频
回复 使用道具 举报
ixiangfeng 发表于 2014-1-14 11:13
加了synchronized在这个函数上是同步函数,简单地说同步函数的作用是加锁,使得两条线程同时执行函数里面 ...

两个线程 都wait() 等待,都在synchronized形容的函数的方法体内  现在不是就相当于都在执行了?
回复 使用道具 举报
75100313 发表于 2014-1-14 11:19
两个线程 都wait() 等待,都在synchronized形容的函数的方法体内  现在不是就相当于都在执行了?  ...

synchronized实现多个线程不能同时操作里面的代码是用监视器或者说是锁,一个线程进去了就会把锁给锁上,其它的线程就进不去了,而wait方法有一个功能就是把锁给打开,synchronized里面的线程一遇到wait方法就会把锁给打开同时在原地呆着,这时因为锁开了所以其它线程可以进去,线程在里面wait是不可能执行代码的,所以两个或者多个线程在里面wait的话并不是说多条线程在里面执行代码
回复 使用道具 举报
ixiangfeng 发表于 2014-1-14 11:28
synchronized实现多个线程不能同时操作里面的代码是用监视器或者说是锁,一个线程进去了就会把锁给锁上, ...

假如说生产者 1号和2号 两条线程  都在执行了wait()方法后  在等待 。 对面消费者一看 没有物品了  那么直接
notifyAll() 把1号和2号都换醒了  1号进程一判断标记是true 马上要生产的时候 ,2号线程 执行 ,也来判断标记。 也是ture。。。结果一下生产了2个。。。会不会这样啊   换句话说 2个线程被唤醒之后 是如何保证 同步的?
回复 使用道具 举报
这个题目如果用blockingqueue来做的话应该简单的多。
回复 使用道具 举报
75100313 发表于 2014-1-14 11:36
假如说生产者 1号和2号 两条线程  都在执行了wait()方法后  在等待 。 对面消费者一看 没有物品了  那么 ...

一个synchronized只有一个锁,像你说的1号和2号被唤醒后,两个都具有执行资格,但是最多只能有一个具有执行权,假如1号线程抢到CPU的执行权,即使1号线程执行到里面一半代码时失去了CPU的执行资格,这时2号线程也不可能执行里面的代码,因为锁还是在1号线程那里,相当于它要动就要拿到锁才动得了
回复 使用道具 举报
ixiangfeng 发表于 2014-1-14 17:23
一个synchronized只有一个锁,像你说的1号和2号被唤醒后,两个都具有执行资格,但是最多只能有一个具有执 ...

十分感谢  谢谢 真心感谢!
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马