JAVA线程交互

    线程的运行都是独立的,但是存在多个线程需要同时访问共享的资源时,需要用到线程的同步(synchronized),就相当于在共享的对象资源上加了一把锁,每次只能一个线程获得对象锁。最简

单的例子:如卖电影票,几个窗口(线程)同时对电影票进行销售,彼此线程都是互斥的,每次只能一个线程去访问电影票(这个对象)。但是也存在一种生产者-消费者的流程,这时需要用到线程的交互(wait()与notify()/notifyAll(),等待-唤醒),比如写个生产包子与卖包子的例子,每次生产包子到100个后就通知去卖包子,当卖包子到0时,就通知生产包子。

1:定义一个包子对象,

public class Manager{

    private  int count;//包子的数量

    private  String name;//包子的名称

    public   int maxcount=100;//包子的最大数量

    public    boolean  k;//用于判断包子是否还有,默认是FALSE,用true代表包子有,通知消费,用false代表包子没有,通知生产。

    //构造函数

    public Manager(String name,int count){

        this.name=name;

        this.count=count;

    }

    public int  getCount(){

        return this.count;

    }

    public int setCount(int y){

        return this.count+=y;

    }


}

//定义一个生产包子的线程

 public class Producer implements Runnable{

    private Manager ma;//定义一个共享对象

    public  Producer(Manager ma){

        this.ma=ma;//保证传递进来的是同一个共享对象

    }

    public void run(){

        //因为不知道是生产线程先运行还是消费线程先运行,所以必须先判断

            while(true){ 

          //无限循环,保证卖完就生产

            synchronized(ma){//传递对象锁

                if(ma.k==true){//状态为true,代表包子已经有了,就等待,通知消费。

                    ma.wait();//这里需要添加try-catch,一旦包子数量有,则需要消费线程去                                            notify(),当前线程就等待唤醒。

                }

                if(ma.getCount<100){//当包子数量少于100个,就生产

                    ma.setCount(5);   

                    System.out.println("生产了5个,总量为;"+ma.getCount());

                }

                ma.k=true;//包子数量大于100个了,所以改变状态

                ma.notify();//通知消费者去消费

                

            }

        }

    }



//定义一个消费线程

public class Custer implements Runnable{

    private Manager ma;

    public Custer(Manager ma){

    this.ma=ma;   

    }

    public void run(){

           while(true){

                synchronized(ma){

                    if(ma.k==false){

                        ma.wait();//当包子的状态为false,代表消费需要等待生产。

                    }

                    if(ma.getCount()>0){

                         ma.setCount(-2);  

                         System.out.println("包子已经消费2个,剩下:"+ma.getCount());

                    }

                    ma.k=false;//包子已经消费完了,需要生产。

                    ma.notify();

                }

        }

        

    }


}

//定义一个主线程类,开始运行

public class Testdemo{

    public static void main(String[] args){

        Manager ma=new Manager("包子",0);//定义一个包子对象

        Producer p=new Producer(ma);//创建生产对象

        Custer   c=new Custer(ma);  //创建消费对象

        Thread   t1=new Thread(p);//创建生产线程对象

        Thread   t2=new Thread(c);   //创建消费线程对象

        

        t1.start();//启动生产线程

        t2.start();  //启动消费线程

    }

}