java 多线程 详解 生产者消费者 问题解决

参考:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html


多生产者  多消费者问题     

有两个生产者 和两个消费者     生产者生产出来的产品要消费掉才能再生产。

方法一:使用synchronized,加等待唤醒机制解决


package yx.multithread;
/**
 * 生产者消费者问题
 * @author yixiang
 *
 */
class Resource {
	private String name;
	private int count=1;
	private boolean flag=false;//生产烤鸭的过程是否需要等待
	public synchronized void set(String name){
		while(flag){
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		this.name=name+count;
		System.out.println(Thread.currentThread().getName()+":::生产者:::"+this.name);
		count++;
		flag=true;
		notifyAll();
	}
	
	public synchronized void out(){
		while(!flag){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("---------------------------------------"+Thread.currentThread().getName()+":::消费者:::"+this.name);
		flag=false;
		notifyAll();
	}
}

class Producer implements Runnable{
	private Resource r;
	public Producer(Resource r){
		this.r=r;
	}
	
	public void run(){
		while(true){
			r.set("烤鸭");
		}
	}
	
}

class Customer implements Runnable{
	private Resource r;
	public Customer(Resource r){
		this.r=r;
	}
	
	public void run(){
		while(true){
			r.out();
		}
	}
	
}

public class ProducerCustomerDemo {
	public static void main(String[] args) {
		Resource r=new Resource();
		Producer p=new Producer(r);
		Customer c=new Customer(r);
		Thread t0=new Thread(p);
		Thread t1=new Thread(p);
		Thread t2=new Thread(c);
		Thread t3=new Thread(c);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
	}
}

方法二:采用jdk1.5的新特性Lock和Condition


package yx.multithread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 生产者消费者问题
 * 利用jdk1.5新特性进行解决
 * @author yixiang
 *
 */
class Resource1 {
	private String name;
	private int count=1;
	private boolean flag=false;//生产烤鸭的过程是否需要等待
	
	//创建一个锁对象
	Lock lock=new ReentrantLock();
	//通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者
	Condition producer_con=lock.newCondition();
	Condition customer_con=lock.newCondition();
	public void set(String name){
		lock.lock();
		try {
			while(flag){
				try {
					producer_con.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			this.name=name+count;
			System.out.println(Thread.currentThread().getName()+":::生产者:::"+this.name);
			count++;
			flag=true;
			customer_con.signal();
		} finally{
			lock.unlock();
		}

	}
	
	public void out(){
		lock.lock();
		try{
			while(!flag){
				try {
					customer_con.await();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println("---------------------------------------"+Thread.currentThread().getName()+":::消费者:::"+this.name);
			flag=false;
			producer_con.signal();
		}finally{
			lock.unlock();
		}

	}
}

class Producer1 implements Runnable{
	private Resource1 r;
	public Producer1(Resource1 r){
		this.r=r;
	}
	
	public void run(){
		while(true){
			r.set("烤鸭");
		}
	}
	
}

class Customer1 implements Runnable{
	private Resource1 r;
	public Customer1(Resource1 r){
		this.r=r;
	}
	
	public void run(){
		while(true){
			r.out();
		}
	}
	
}

public class ProducerCustomerDemo1 {
	public static void main(String[] args) {
		Resource1 r=new Resource1();
		Producer1 p=new Producer1(r);
		Customer1 c=new Customer1(r);
		Thread t0=new Thread(p);
		Thread t1=new Thread(p);
		Thread t2=new Thread(c);
		Thread t3=new Thread(c);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
	}
}


再给大家出三道面试题

第一题:设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1


package yx.multithread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1
 * 这里还没有使用等待唤醒机制
 * @author yixiang
 *
 */
class Info{
	private int j=0;
	
	Lock lock=new ReentrantLock();
	
	public void add(){
		lock.lock();
		try {
			j++;
			System.out.println(Thread.currentThread().getName()+":::add:"+j);
		} finally{
			lock.unlock();
		}
	}
	
	public void sub(){
		lock.lock();
		try {
			j--;
			System.out.println("-------------------------"+Thread.currentThread().getName()+"sub:"+j);
		} finally{
			lock.unlock();
		}
	}
}

class Adder implements Runnable{
	private Info info;
	public Adder(Info info){
		this.info=info;
	}
	public void run(){
		info.add();
	}
}

class Suber implements Runnable{
	private Info info;
	public Suber(Info info){
		this.info=info;
	}
	public void run(){
		info.sub();
	}
}

public class Test1 {

	public static void main(String[] args) {
		Info info=new Info();
		Adder adder=new Adder(info);
		Suber suber=new Suber(info);
		Thread t0=new Thread(adder);
		Thread t1=new Thread(adder);
		Thread t2=new Thread(suber);
		Thread t3=new Thread(suber);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
		
	}

}

第二题:子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程循环100次,如此循环50次,请写出程序


package yx.multithread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程循环100次,如此循环50次,请写出程序
 * @author yixiang
 *
 */
class Bussiness{
	private boolean flag=false;//主线程是否需要等待的标志
	
	Lock lock=new ReentrantLock();
	Condition main_con=lock.newCondition();
	Condition sub_con=lock.newCondition();
	
	public void mainThread(){
		lock.lock();
		try {
			while(flag){
				try {
					main_con.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
			for(int i=0;i<10;i++){
				System.out.println("主线程"+i);
			}
			flag=true;
			sub_con.signal();
		} finally{
			lock.unlock();
		}
		
	}
	
	public void subThread(){
		lock.lock();
		try{
			while(!flag){
				try {
					sub_con.await();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			for(int i=0;i<100;i++)
				System.out.println("-------------------------------子线程:"+i);
			flag=false;
			main_con.signal();
			
		}finally{
			lock.unlock();
		}
	}
		
}

class MainRunnable implements Runnable{
	private Bussiness b;
	public MainRunnable(Bussiness b){
		this.b=b;
	}
	public void run(){
		for(int i=0;i<50;i++)
			b.mainThread();
	}
}

class SubRunnable implements Runnable{
	private Bussiness b;
	public SubRunnable(Bussiness b){
		this.b=b;
	}
	public void run(){
		for(int i=0;i<50;i++)
			b.subThread();
	}
}

public class Test2 {
	public static void main(String[] args) {
		Bussiness b=new Bussiness();
		MainRunnable main=new MainRunnable(b);
		SubRunnable sub=new SubRunnable(b);
		Thread t0=new Thread(main);
		Thread t1=new Thread(sub);
		t0.start();
		t1.start();
	}
}


第三题:使用长度为10的缓冲区进行缓存生产者的商品。

package yx.multithread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


class BoundedBuffer {
	   final Lock lock = new ReentrantLock();
	   final Condition notFull  = lock.newCondition(); 
	   final Condition notEmpty = lock.newCondition(); 

	   final Object[] items = new Object[10];
	   int putptr, takeptr, count;

	   public void put(Object x) throws InterruptedException {
	     lock.lock();
	     try {
	       while (count == items.length) 
	         notFull.await();
	       items[putptr] = x; 
	       if (++putptr == items.length) putptr = 0;
	       ++count;
	       for(int i=0;i<count;i++){
	    	   System.out.print(items[i]+",");
	       }
	       System.out.println();
	       notEmpty.signal();
	     } finally {
	       lock.unlock();
	     }
	   }

	   public Object take() throws InterruptedException {
	     lock.lock();
	     try {
	       while (count == 0) 
	         notEmpty.await();
	       Object x = items[takeptr]; 
	       if (++takeptr == items.length) takeptr = 0;
	       --count;
	       for(int i=0;i<count;i++){
	    	   System.out.print(items[i]+",");
	       }
	       System.out.println();
	       notFull.signal();
	       return x;
	     } finally {
	       lock.unlock();
	     }
	} 
}

class PutRunnable implements Runnable{
	private BoundedBuffer b;
	public PutRunnable(BoundedBuffer b){
		this.b=b;
	}
	public void run(){
		int i=0,j=0;
		while(j<100){
			try {
				b.put(i);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			i++;
			j++;
		}
	}
}

class TakeRunnable implements Runnable{
	private BoundedBuffer b;
	public TakeRunnable(BoundedBuffer b){
		this.b=b;
	}
	public void run(){
		int i=0,j=0;
		while(j<100){
			try {
				b.take();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			j++;
		}
	}
}


public class Buffer {

	public static void main(String[] args) {
		BoundedBuffer b=new BoundedBuffer();
		PutRunnable p=new PutRunnable(b);
		TakeRunnable t=new TakeRunnable(b);
		new Thread(p).start();
		new Thread(t).start();
	}

}



你可能感兴趣的:(java 多线程 详解 生产者消费者 问题解决)