• 使用Notify 和 wait ,使用Linklist实现生产者消费者问题


    ref:http://www.cnblogs.com/happyPawpaw/archive/2013/01/18/2865957.html

    注释很清楚的,

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    //产品
    class Product
    {
    	 String name=null;
    	public Product(String name)
    	{
    		this.name=name;
    	}
    	
    }
    
    class  Buffer
    {
      private Queue<Product> queue=new LinkedList<Product>();//一个普通队列,同时作为同步的对象
      private final int size=5;  //最大长度为,可以自己调整
      public void add(Product p)//
      {
    	  synchronized (queue) {
    		  while(queue.size()==size)
    		  {
    			  System.out.println(Thread.currentThread().getName()+"队列已经满了,生产者释放锁");
    			  try {
    				queue.wait(); //队列未满,则放弃锁,进行挂起,等到queue,notify,有个线程会重新从wait后运行
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		  }
    		  queue.offer(p);
    		 
    		  System.out.println(Thread.currentThread().getName()+"入队    "+queue.size());
    		  
    		  queue.notify();//加入一个元素,则通因为为空而挂起的线程
    		
    	}
    	  
     }
      
      public void remove()
      {
    	  synchronized (queue) {
    		  while(queue.size()<=0)
    		  {
    
    			  System.out.println(Thread.currentThread().getName()+"队列为空,释放锁");
    			  try {
    				queue.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		  }
    		  queue.poll();
    		  System.out.println(Thread.currentThread().getName()+"出队,剩下"+queue.size());
    		  queue.notify();
    		
    	}
    	  
      }
    	
    
    }
    
    class Producer implements Runnable
    {
    	private Buffer buf; //所有线程共享一个buffer,所以作为参数
    	
    	public Producer(Buffer buf)
    	{
    		this.buf=buf;
    	}
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		for(int i=0;i<10;i++)
    		{
    			try {
    				Thread.sleep(3000);  //控制生产速度,可以让生产快,还是消费快,来观察队列的情况,
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			buf.add(new Product("zhang "+i));
    		}
    		
    		
    	}
    	
    
    
    }
    class Customer implements Runnable
    {
      private Buffer buf=null;
      public Customer(Buffer buf)
      {
    	  this.buf=buf;
      }
    	@Override
    	public void run() {
    		for(int i=0;i<10;i++)
    		{
    			try {
    				Thread.sleep(1);//控制生产速度,,
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}//
    			buf.remove();
    		}
    		
    	}
    	
    
    }
    
    public class 生产消费者 {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
    		//学学使用线程池
    		Buffer buf=new Buffer();
    		ExecutorService exe=Executors.newCachedThreadPool();//一个简单的线程池
    		int i=0;
    		while(i++<2)
    		{
    			exe.submit(new Producer(buf)); //生产者两个线程
    			
    		}
    		i=0;
    		while(i++<2)
    		{
    			exe.submit(new Customer(buf));//消费者两个线程
    		}
    		exe.shutdown();
    
    	}
    
    }
    
  • 相关阅读:
    PHP 将二维数组中某列值作为数组的键名
    MySQL 8下忘密码后重置密码
    单一职责原则
    Linux下安装SVN服务端小白教程
    go 代码玩耍
    centos7 docker开启认证的远程端口2376配置教程
    Dockerfile RUN,CMD,ENTRYPOINT命令区别
    wait-for-it.sh脚本控制docker-compose启动顺序详解
    阿里云服务器漏洞修复_2020.5.22
    Let's Encrypt 免费通配符 SSL 证书申请教程
  • 原文地址:https://www.cnblogs.com/hansongjiang/p/3859238.html
Copyright © 2020-2023  润新知