java多线程1-生产者与消费者

1.5之前的写法.

/*
生产者消费者
两个线程生产,两个线程消费.
而且要是生产一个消费一个.

主要问题:使用notifyAll会唤醒本方线程,这个问题要lock和conditions来处理.
如果不用notifyAll,只用notify所有线程都会wait.
*/
class  TestMain
{
    public static void main(String[] args) 
    {
        Resource res = new Resource();
        Producer pro = new Producer(res);
        Consumer con = new Consumer(res);
        Thread t1 = new Thread(res);
        Thread t2 = new Thread(pro);
        Thread t3 = new Thread(res);
        Thread t4 = new Thread(pro);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class Resource
{
    private String name;
    private int count=1;
    private boolean flag =false;

    public synchronized void set(String name){
        if(flag){
            try{
                wait();//线程会停在这里,但是当线程被唤醒的时候,一样要循环判断标记.所以if要改成while
            }catch(Exception e){
                //如果出异常,方法结束,就出了synchronized代码块锁也有释放了.这点不像lock.nulock().nulock是一定要执行的,出了异常,方法结束也是要执行的.
            }
        }            
        this.name=name+"--"+count++;
        System.out.println(Thread.curentThread().getName()+"生产的"+this.name);
        flag=true;
        this.notify();//这里唤醒的时候可能唤醒的是本方线程,导致所有线程wait,所以要用 notifyAll()
    }
    public synchronized void out(){
        if(!flag){
            try{
                wait();
            }catch(Exception e){
                //
            }
        }
        System.out.println(Thread.curentThread().getName()+"消费者"+this.name);
        flag=false;
        this.notify();
    }
}
class Producer implements Runnable
{
    private Resource res;
    Producer(Resource res){
        this.res=res;
    }
    @Override
    public void run(){
        while(true){
            res.set("+商品+");
        }
    }
}

class Consumer implements Runnable
{
    private Resource res;
    Producer(Resource res){
        this.res=res;
    }
    @Override
    public void run(){
        while(true){
            res.out();
        }
    }
}

1.5之后的写法

/*
生产与消费者
jdk1.5 之后的Lock与Condition
可以保证唤醒的是对方线程,可以唤醒对方一个,也可以是所有.主要看用的是signal与signalAll()

*/
class  TestMain
{
    public static void main(String[] args) 
    {
        //要操作的数据,资源
        Resource res = new Resource();
        //两个生产,消费线程
        Producer pro = new Producer(res);
        Resource res = new Resource();
        Producer pro = new Producer(res);
        Consumer con = new Consumer(res);
        Thread t1 = new Thread(res);
        Thread t2 = new Thread(pro);
        Thread t3 = new Thread(res);
        Thread t4 = new Thread(pro);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
/*
  资源类,里面的要操作的数据,操作数据的方法,标记,锁,Condition.
*/
class Resource
{
    private String name;
    private int count=1;
    private boolean flag =false;
    
    //1.5之后lock代替了,syschronized
    private Lock lock =new ReentrantLock();
    //Condition 代替了Objcet里面的wait,notify,notifyAll
    private Condition condition1=lock.newCondition();
    
    //用来分组线程,本方只唤醒对方线程的操作.
    private Condition condition2=lock.newCodition();

    //去掉了synchronized关键字
    public void set(String name){

        while(flag){
            try{
                condition1.await();
            }catch(Exception e){
                //这里一但出异常,因为还没有执行lock.unlock()会,所以方法结束但是锁还没有释放,所以一定要入finally里面去执行nulock();
            }
        }            
        this.name=name+"--"+count++;
        System.out.println(Thread.curentThread().getName()+"生产的"+this.name);
        flag=true;
        //condition.signalAll();//这样可能会唤醒本方线程.用signal()会全部等待.

        condition2.signal()//这样可以保证唤醒的是对方线程.
        lock.unlock();
    }
    //去掉synchronized
    public  void out(){
        lock.loct();
        try{
            while(!flag){
                condition2.await()//线程被唤醒后,一定要循环判断标记
            }
            System.out.println(Thread.curentThread().getName()+"消费者"+this.name);
            flag=false;
            //condition.signalAll();//这里同样可能会唤醒本方的线程,要改的
            condition2.signa();
        }catch(InterrputedException e){
            //await()的时候可会出异常,出了异常方法结束了,但也定要nulock()
        }finally{
            lock.nulock();
        }
    }
}
/*
生产者线程
*/
class Producer implements Runnable
{
    private Resource res;
    Producer(Resource res){
        this.res=res;
    }
    @Override
    public void run(){
        while(true){
            res.set("+商品+");
        }
    }
}
/*
消费者线程
*/
class Consumer implements Runnable
{
    private Resource res;
    Producer(Resource res){
        this.res=res;
    }
    @Override
    public void run(){
        while(true){
            res.out();
        }
    }
}

你可能感兴趣的:(java多线程1-生产者与消费者)