生产者2

来源:互联网 发布:太行航空发动机知乎 编辑:程序博客网 时间:2024/06/05 06:18
class ThreadDemo9{
main:
  java.util.List<Integer> list = new java.util.ArrayList<Integer> list;
  Productor p = new Productor("pro",list);
  Consumer c = new Consumer("con",list);
  p.start();
  c.start();
}


class Productor extends Thread{ 
  private String name;
  private java.util.List<Integer> list;
  public Productor(String name, java.util.List<Integer> list){
    this.name = name;
    this.list = list;
  }
  public void run(){
    int i =0;
    while(true){

      list.add(new Integer(i++));

      print(i);

  }
}


class Consumer extends Thread{
  private String name;
  private java.util.List<Integer> list;
  public Consumer(String name, java.util.List<Integer> list){
    this.name = name;
    this.list = list;
  }
  public void run(){
    int i =0;
    while(true){
      if(list.size()>0){

        int i =list.remove(0);

        try{

          Thread.sleep(2000);  //让生产速度大于消费速度

        }

        catch(Exception e){}

        print(i);

        
      }
    }
  }

}


java -Xmx10m ThreadDemo9 

堆溢出 因为生产太快 消费太慢

-------------------------------------------------

class Pool{

  private java.util.List<Integer> list = new java.util.ArrayList<Integer>();

  private int MAX =100;

  public void add(int n){

    synchronized(this){    //wait出异常 补上 同一个时刻 只能有一个线程调用这个方法

      if(list.size()>=MAX){

        try{

          this.wait(); 

          //等待后面的代码时可达的 因为wait会回来的 当别人通知你的时候 回到wait下面那句话继续执行

        }

        catch(Exception e){

          e.printStackTrace();   //非法监控异常 IllegalMonitorStateException 因为wait方法是Object的方法 要获得锁旗标 才能调用wait 所以要加                

                                              //synchronize

        } 

      }

      list.add(n);

    }  

  }


  public void remove(){

    synchronized(this){                              //后面加上去 为了使用wait

      try{                                                     //*

        if(list.size() == 0){

          this.wait(); 等待生产者往里面放元素

        }

        else{

          int i = list.remove(0);

          this.notify(); 

          return i;

        }

      }

      catch(Exception e){

          e.printStackTrace();

      }                                                             *//

      //if(list.size()>0){

      //  return list.remove(0);

      //}

      return -1;

    }

  }

}


class Productor extends Thread{ 
  private String name;
  private Pool pool;
  public Productor(String name, Pool pool){
    this.name = name;
    this.pool= pool;
  }
  public void run(){
    int i =0;
    while(true){

      pool.add(i++);

      print(i);

  }
}


class Consumer extends Thread{
  private String name;
  private java.util.List<Integer> list;
  public Consumer(String name, java.util.List<Integer> list){
    this.name = name;
    this.list = list;
  }
  public void run(){
    int i =0;
    while(true){

      int i =pool.remove();

      try{

      }

      catch(Exception e){

        Thread.sleep(100);

      }
      print(i);      

    }
  }

}


main:

Pool pool = new Pool()

Productor p = new Productor("pro",pool);

Consumer c = new Consumer("con", pool);

p.start();

c.start();

-------------------

任何对象都能作为锁旗标


状态:

synchronized(xxx){

wait();

}

------------------------

sleep方法不会释放监控权 监控权是对lock那个对象而言

sleep释放cpu抢占权,也就是说 sleep时候 同步的那一段代码的lock 不会被其他代码用到

释放cpu抢占权 和 锁旗标的监控权没有关系

wait 让当前线程进入锁旗标的等待队列 释放cpu抢占权 释放锁旗标的监控权 等待锁旗标发出的通知 等到有人调用Object.notify()方法

notify方法会通知等待队列中的线程 你们可以唤醒了 随机挑一个唤醒 线程就具有抢占cpu的权限 监控权 但是线程能不能抢到看造化

一次notify只提醒一个线程

--------------------------------------------------------

wait这个方法只有获得锁旗标的监控权时候 才能用 也就是说只能在同步代码块里面调用

同理 notify也要在同步代码块调用CIA可以

----------------------------------------------------------

add:

synchronized(this){

  try{

    if(list.size()>=MAX){

      this.wait();

    }

    else{

      list.add(n);

      this.notify();

    }

  }catch(Exception e){

    e.printStackTrace();

  }

}

-------------------------------------------------------

改变add 中的:

if(list.size()>=MAX){

      this.wait();

    }

变成 

while(list.size()>=MAX){

      this.wait();

}

也就是说 唤醒后 还要判断 执行下while语句

---------------------------------------------

remove中也要用while

    synchronized(this){                              //后面加上去 为了使用wait

      try{                                                     //*

        while(list.size() == 0){

          this.wait(); 等待生产者往里面放元素

        }

        

          int i = list.remove(0);

          this.notify(); 

          return i;

        

      }

      catch(Exception e){

          e.printStackTrace();

      }                                                             *//

      return -1;

    }

  }

}


-------------------------------------------------------

main中 两个生产者 所以这里要

class Productor extends Thread{

  static int i =0; 
  private String name;
  private java.util.List<Integer> list;
  public Productor(String name, java.util.List<Integer> list){
    this.name = name;
    this.list = list;
  }
  public void run(){
    //int i =0;
    while(true){

      list.add(new Integer(i++));

      print(i);

  }
}

----------------------------------------------------------

死锁 

比如 一个生产者p 两个消费者s1 s2

当p等待队列中 s1也在等待队列 s2换醒了notifys1 然后 s1也进入排队 三个都在排队

--------------------------------------------------------

notifyAll 所有都notify  

notify 只有一个可以通过唤醒

解决死锁的方法

1.notifyAll() 通知所有线程可以抢占cpu和锁旗标监控权

2.wait(1000); 等待固定的时间

--------------------------------

原创粉丝点击