参考: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(); } }
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(); } }
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(); } }