初试java_thread生产者消费者

8年前
自己给自己想了个题目,1个线程生产笔,1个线程取,在1箱转满10个的时候取走
  分析:client 和service线程共享一个盒子变量,  ,线程共享会涉及到  线程锁机制  ,目前我掌握的线程锁,主要是通过 java关键字 synchronized,synchronized可以锁对象,方法,锁某块 
  比如syschronized (对象){
do  some thing
}
锁方法 public synchronized void test()
{
}
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
  二、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
  三、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。
  四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
  五、以上规则对其它对象锁同样适用
 
如果要保证线程的有序执行,还的加上wait() ,notify()的方法配和
 wait()方法,将线程进入阻塞队列,释放锁资源,等待其他的线程唤醒,
notify()方法,唤醒阻塞队列中的线程,进入就绪队列,
下面我试验的列子
Box是共享变量 ,
public class Box {
    private  int size=100;
       private ArrayList list=new ArrayList();
   
    public  synchronized boolean put(Pen p)
    {
     if(list.size()>=size)  //不能放
     { 
   try{  
     System.out.println("放满等待取走...");
      wait();
   }catch(Exception e)
   {
   e.printStackTrace(); 
   }      return  false;
     }     
     list.add(p);
    this.notify();//唤醒阻塞队列的某线程到就序队列
     return true;
    }
   
    public synchronized  void get()
    {     
     //如果>size那就取走,
       if(list.size()>=size)
       {  int j=list.size();
             list.clear();      
        System.out.println("取走了");       
           this.notify();//唤醒阻塞队列的某线程到就序队列        
       }else
      try{
       wait();
      }catch(Exception e)
      {
       e.printStackTrace();
      }     
    }    
    public  static void main(String []args)
    {    
     Box box=new Box();
     prodThread  prodthread=new prodThread(box);
     prodthread.start();
     clientThread client=new clientThread(box);
     client.start();     
    }
   
public class clientThread extends Thread {
 private Box box;
 int i=0;
 
 
 @Override
 public void run() {
  // TODO Auto-generated method stub
  
  while(true)
  {
   
  
   box.get();
   //System.out.println("getJ==="+i);
   i=i+1;
  
   
  }
  
  
 }
 
 
 
 public clientThread(Box box)
 {
  this.box=box;
 }
}
public class prodThread  extends Thread {
    
 
 private Box b;
 private int i=0;
 
 
 
 public prodThread(Box box)
 {
  this.b=box;
 }
 
 @Override
 public void run() {
  // TODO Auto-generated method stub
  while(true)
  {
  Pen p=new Pen();
  
 
  
  if(b.put(p))
    {  i=i+1;
     //System.out.println("添加成功i=="+i);
    }
  /* else
    try{//休眠
     this.sleep(5000l);
    }catch(Exception e)
    {
     e.printStackTrace();
    }
    */
  //super.run();
  }
 } 
 
 public static void main(String []args)
 {
  
 }
}
结果:
放满等待取走...
取走了
放满等待取走...
取走了
放满等待取走...
取走了
 
 
如果不加 wait(),notify将是无序的