实例
模仿生产者和消费者的模式
先来个两个线程的
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Res r=new Res();
Pro in=new Pro(r);
Cou out=new Cou(r);
Thread t1=new Thread(in);
Thread t2=new Thread(out);
t1.start();
t2.start();
}
}
class Res
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name)
{
if(flag)
try{wait();}catch(Exception e){}
this.name=name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);
flag=true;
this.notify();
}
public synchronized void out()
{
if(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
flag=false;
this.notify();
}
}
class Pro implements Runnable
{
private Res r;
Pro(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.set("--商品--");
}
}
}
class Cou implements Runnable
{
private Res r;
Cou(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
这样就OK了
下面就试试四个线程的,两个线程生产,两个线程消费;
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Res r=new Res();
Pro in=new Pro(r);
Cou out=new Cou(r);
Thread t1=new Thread(in);
Thread t2=new Thread(in);
Thread t3=new Thread(out);
Thread t4=new Thread(out);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Res
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name)
{
if(flag)
try{wait();}catch(Exception e){}
this.name=name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);
flag=true;
this.notify();
}
public synchronized void out()
{
if(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
flag=false;
this.notify();
}
}
class Pro implements Runnable
{
private Res r;
Pro(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.set("--商品--");
}
}
}
class Cou implements Runnable
{
private Res r;
Cou(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
但结果是多生产少消费,并不是我们想要的一生产一消费;
改良代码
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Res r=new Res();
Pro in=new Pro(r);
Cou out=new Cou(r);
Thread t1=new Thread(in);
Thread t2=new Thread(in);
Thread t3=new Thread(out);
Thread t4=new Thread(out);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Res
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name)
{
while(flag)
try{wait();}catch(Exception e){}
this.name=name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);
flag=true;
this.notifyAll();
}
public synchronized void out()
{
while(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
flag=false;
this.notifyAll();
}
}
class Pro implements Runnable
{
private Res r;
Pro(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.set("--商品--");
}
}
}
class Cou implements Runnable
{
private Res r;
Cou(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
对于多个生产者和消费者。
为什么要定义while判断标记。
原因:让被唤醒的线程在一次判断标记。
为什么定义notifyAll?
因为需要唤醒对方线程。
以为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。
JDK新版中提供了多线程升级解决方案。
将同步Syschronized替换成现实Lock操作;
将Object中的wait, notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
实现了本方只唤醒对方的操作;
import java.util.concurrent.locks.*;
class ProducerConsumerDemo2
{
public static void main(String[] args)
{
Res r=new Res();
Pro in=new Pro(r);
Cou out=new Cou(r);
Thread t1=new Thread(in);
Thread t2=new Thread(in);
Thread t3=new Thread(out);
Thread t4=new Thread(out);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Res
{
private String name;
private int count=1;
private boolean flag=false;
private Lock lock=new ReentrantLock();
private Condition condition_in=lock.newCondition();
private Condition condition_out=lock.newCondition();
public void set(String name)throws InterruptedException
{
lock.lock();
try
{
while(flag)
condition_in.await();
this.name=name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);
flag=true;
condition_out.signal();
}
finally
{
lock.unlock();//解锁对象一定要执行
}
}
public void out()throws InterruptedException
{
lock.lock();
try
{
while(!flag)
condition_out.await();
System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
flag=false;
condition_in.signal();
}
finally
{
lock.unlock();
}
}
}
class Pro implements Runnable
{
private Res r;
Pro(Res r)
{
this.r=r;
}
public void run()
{
try
{
while(true)
{
r.set("--商品--");
}
}
catch (InterruptedException e)
{
}
}
}
class Cou implements Runnable
{
private Res r;
Cou(Res r)
{
this.r=r;
}
public void run()
{
try
{
while(true)
{
r.out();
}
}
catch (InterruptedException e)
{
}
}
}