您的位置:首页 > 编程语言 > Java开发

java多线程1-生产者与消费者

2016-03-23 22:38 429 查看
1.5之前的写法.

/*
生产者消费者
两个线程生产,两个线程消费.
而且要是生产一个消费一个.

主要问题:使用notifyAll会唤醒本方线程,这个问题要lock和conditions来处理.
如果不用notifyAll,只用notify所有线程都会wait.
*/
class  TestMain
{
public static void main(String[] args)
{
Resource res = new Resource();
Producer pro = new Producer(res);
Consumer con = new Consumer(res);
Thread t1 = new Thread(res);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(res);
Thread t4 = new Thread(pro);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource
{
private String name;
private int count=1;
private boolean flag =false;

public synchronized void set(String name){
if(flag){
try{
wait();//线程会停在这里,但是当线程被唤醒的时候,一样要循环判断标记.所以if要改成while
}catch(Exception e){
//如果出异常,方法结束,就出了synchronized代码块锁也有释放了.这点不像lock.nulock().nulock是一定要执行的,出了异常,方法结束也是要执行的.
}
}
this.name=name+"--"+count++;
System.out.println(Thread.curentThread().getName()+"生产的"+this.name);
flag=true;
this.notify();//这里唤醒的时候可能唤醒的是本方线程,导致所有线程wait,所以要用 notifyAll()
}
public synchronized void out(){
if(!flag){
try{
wait();
}catch(Exception e){
//
}
}
System.out.println(Thread.curentThread().getName()+"消费者"+this.name);
flag=false;
this.notify();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res){
this.res=res;
}
@Override
public void run(){
while(true){
res.set("+商品+");
}
}
}

class Consumer implements Runnable
{
private Resource res;
Producer(Resource res){
this.res=res;
}
@Override
public void run(){
while(true){
res.out();
}
}
}


1.5之后的写法

/*
生产与消费者
jdk1.5 之后的Lock与Condition
可以保证唤醒的是对方线程,可以唤醒对方一个,也可以是所有.主要看用的是signal与signalAll()

*/
class  TestMain
{
public static void main(String[] args)
{
//要操作的数据,资源
Resource res = new Resource();
//两个生产,消费线程
Producer pro = new Producer(res);
Resource res = new Resource();
Producer pro = new Producer(res);
Consumer con = new Consumer(res);
Thread t1 = new Thread(res);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(res);
Thread t4 = new Thread(pro);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
资源类,里面的要操作的数据,操作数据的方法,标记,锁,Condition.
*/
class Resource
{
private String name;
private int count=1;
private boolean flag =false;

//1.5之后lock代替了,syschronized
private Lock lock =new ReentrantLock();
//Condition 代替了Objcet里面的wait,notify,notifyAll
private Condition condition1=lock.newCondition();

//用来分组线程,本方只唤醒对方线程的操作.
private Condition condition2=lock.newCodition();

//去掉了synchronized关键字
public void set(String name){

while(flag){
try{
condition1.await();
}catch(Exception e){
//这里一但出异常,因为还没有执行lock.unlock()会,所以方法结束但是锁还没有释放,所以一定要入finally里面去执行nulock();
}
}
this.name=name+"--"+count++;
System.out.println(Thread.curentThread().getName()+"生产的"+this.name);
flag=true;
//condition.signalAll();//这样可能会唤醒本方线程.用signal()会全部等待.

condition2.signal()//这样可以保证唤醒的是对方线程.
lock.unlock();
}
//去掉synchronized
public  void out(){
lock.loct();
try{
while(!flag){
condition2.await()//线程被唤醒后,一定要循环判断标记
}
System.out.println(Thread.curentThread().getName()+"消费者"+this.name);
flag=false;
//condition.signalAll();//这里同样可能会唤醒本方的线程,要改的
condition2.signa();
}catch(InterrputedException e){
//await()的时候可会出异常,出了异常方法结束了,但也定要nulock()
}finally{
lock.nulock();
}
}
}
/*
生产者线程
*/
class Producer implements Runnable
{
private Resource res;
Producer(Resource res){
this.res=res;
}
@Override
public void run(){
while(true){
res.set("+商品+");
}
}
}
/*
消费者线程
*/
class Consumer implements Runnable
{
private Resource res;
Producer(Resource res){
this.res=res;
}
@Override
public void run(){
while(true){
res.out();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: