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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨永胜 高级黑马   /  2012-12-11 10:50  /  1968 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨永胜 于 2012-12-12 15:00 编辑

RT,这部分搞得很晕乎,求代码,求解释!{:soso_e118:}

5 个回复

倒序浏览
本帖最后由 李培根 于 2012-12-11 13:51 编辑

/*
生产者,消费者。
多生产者多消费者。

if判断标记只有一次,会导致不该运行的线程运行了,会出现数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行。

notify:只能唤醒一个线程,如果唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
notifyAll 解决了本方线程一定会唤醒对方线程的问题。

*/
class Resource2{
        private String name;
        private int count = 1;
        private boolean flag = false;
        public synchronized void set(String name){//加同步,保证线程安全
                while(flag)//判断标记,为真等待
                        try{this.wait();}
                        catch(InterruptedException e){}
                this.name = name + count;
                count++;
                System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);
                flag = true;//修改标记
                notifyAll();//唤醒全部,确保唤醒对方
        }
        public synchronized void get(){
                while(!flag)//判断标记,没有就等待
                        try{this.wait();}
                        catch(InterruptedException e){}
                System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);
                flag = false;//修改标记
                notifyAll();//唤醒全部,确保唤醒对方
        }
}

class Producer implements Runnable{
        Resource2 r;
        Producer(Resource2 r){
                this.r = r;
        }
        
         public void run(){
                while(true){
                        r.set("烤鸭");
                }
        }
}

class Consumer implements Runnable{
        
        Resource2 r;
        Consumer(Resource2 r){
                this.r = r;
        }
        public void run(){
                while(true){
                        r.get();
                }
        }
}

public class ConsumerDemo2 {
        public static void main(String[] args) {
                Resource2 r = new Resource2();
               
                Producer pro = new Producer(r);
                Consumer con = new Consumer(r);
               
                Thread t0 = new Thread(pro);
                Thread t1 = new Thread(pro);
                Thread t2 = new Thread(con);
                Thread t3 = new Thread(con);
               
                t0.start();
                t1.start();
                t2.start();
                t3.start();               
        }
}
回复 使用道具 举报

jdk1.5以后将同步和锁封装成了对象进行了优化。

Lock接口:出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成了显示锁操作。
        同时更为灵活,可以一个锁上加上多组监视器。
Condition接口:出现替代了object中的wait  notify  notifyAll方法。
                        将这些监视器方法单独进行了封装,变成Condition监视器对象。
                        可以和任意的锁进行组合。
不同notifyAll(),直接通过producer_con.signal();唤醒对方,提高效率。
       
*/
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Resource3{
        private String name;
        private int count = 1;
        private boolean flag = false;
        //创建一个锁对象。
        Lock lock = new ReentrantLock();
        //通过已有的锁获取该锁上的监视器对象。
//        Condition c = lock.newCondition();
        //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。
        Condition producer_con = lock.newCondition();
        Condition consumer_con = lock.newCondition();       
       
       
        public void set(String name){               
                lock.lock();
                try{
                        while(flag)
                                try{producer_con.await();}
                                catch(InterruptedException e){}
                        this.name = name + count;
                        count++;
                        System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);               
                        flag = true;
                        consumer_con.signal();
                }
                finally{
                        lock.unlock();
                }
        }
        public void get(){
                lock.lock();
                try{
                        while(!flag)
                                try{consumer_con.await();}
                                catch(InterruptedException e){}
                        System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);
                        flag = false;
                        producer_con.signal();
                }
                finally{
                        lock.unlock();
                }
        }
}

class Producer2 implements Runnable{
        Resource3 r;
        Producer2(Resource3 r){
                this.r = r;
        }       
        public void run(){
                while(true){
                        r.set("烤鸭");
                }
        }
}

class Consumer2 implements Runnable{       
        Resource3 r;
        Consumer2(Resource3 r){
                this.r = r;
        }
        public void run(){
                while(true){
                        r.get();
                }
        }
}

public class NewJDKDemo3 {
        public static void main(String[] args) {
                Resource3 r = new Resource3();
               
                Producer2 pro = new Producer2(r);
                Consumer2 con = new Consumer2(r);
               
                Thread t0 = new Thread(pro);
                Thread t1 = new Thread(pro);
                Thread t2 = new Thread(con);
                Thread t3 = new Thread(con);
               
                t0.start();
                t1.start();
                t2.start();
                t3.start();               
        }
}
回复 使用道具 举报
不错!给力
回复 使用道具 举报
杨永胜 发表于 2012-12-11 13:58
不错!给力

兄弟问下你问什么这么多的积分?
回复 使用道具 举报
李培根 发表于 2012-12-11 14:06
兄弟问下你问什么这么多的积分?

我不知道,当初黑马刚出的时候我就注册了,时间久了吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马