生产者和消费者的经典问题 java编程实现

1、使用synchronized

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
* synchronized实现的生产者和消费者
*/
public class ProducerCustomerWithSynchronized {

Executor pool = Executors.newFixedThreadPool(10);

//仓库
private List<String> storageList = new LinkedList<String>();

//仓库容量
private int MAX_SIZE = 3;

//仓库为空
private int ZERO = 0;

//生产者线程
private class Producer implements Runnable{

    //生产方法,需同步
    private void produce(){
        synchronized (storageList) {
            System.out.println(Thread.currentThread().getName()+"进入仓库,准备生产!");
            try {
                if(storageList.size()==MAX_SIZE) {
                    System.out.println("仓库已满!等待消费者消费");
                    Thread.sleep(1000);
                    storageList.wait();//当前线程放弃锁,处于等待状态,让其他线程执行
                }
                if(storageList.size()<MAX_SIZE) {
                    String name = "产品"+new Random().nextInt();
                    storageList.add(name);
                    System.out.println(Thread.currentThread().getName()+"往仓库中生产了一个产品!");
                }
                Thread.sleep(1000);
                storageList.notifyAll();//当前线程放弃锁,唤醒其他线程

            }catch(InterruptedException ie) {
                System.out.println("中断异常");
                ie.printStackTrace();
            }

        }
    }

    @Override
    public void run() {
        while(true) {
            produce();
        }
    }
}

//消费者线程
private class Customer implements Runnable{

    //消费方法,需同步
    private void consume() {
        synchronized (storageList) {
            System.out.println(Thread.currentThread().getName()+"进入仓库,准备消费!");
            try {
                if(storageList.size()==ZERO) {
                    System.out.println("仓库已空!等待生产者生产");
                    Thread.sleep(1000);
                    storageList.wait();//当前线程放弃锁,处于等待状态,让其他线程执行
                }
                if(storageList.size()!=ZERO) {
                    System.out.println(Thread.currentThread().getName()+"从仓库取得产品:"+storageList.remove(0));
                }
                Thread.sleep(1000);
                storageList.notifyAll();//当前线程放弃锁,唤醒其他线程
            }catch(InterruptedException ie) {
                System.out.println("中断异常");
                ie.printStackTrace();
            }

        }
    }

    @Override
    public void run() {
        while(true) {
            consume();
        }
    }

}

//启动生产者和消费者线程
public void start() {
    for(int i=1;i<5;i++) {
        //new Thread(new Producer()).start();
        //new Thread(new Customer()).start();
        pool.execute(new Producer());
        pool.execute(new Customer());
    }

}

public static void main(String[] args) {
    ProducerCustomerWithSynchronized pc = new ProducerCustomerWithSynchronized();
    pc.start();
}

}

2.使用Lock

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* Lock实现的生产者和消费者
*
*/
public class ProducerCustomerWithLock {

Executor pool = Executors.newFixedThreadPool(10);

//仓库
private List<String> storageList = new LinkedList<String>();

//仓库容量
private int MAX_SIZE = 3;

//仓库为空
private int ZERO = 0;

//获取锁对象
private Lock lock = new ReentrantLock();

//仓库满了,绑定生产者线程
private Condition full = lock.newCondition();

//仓库为空,绑定消费者线程
private Condition empty = lock.newCondition();

//生产者线程
private class Producer implements Runnable{

    //生产方法,需同步
    private void produce(){
        if(lock.tryLock()) {
            System.out.println(Thread.currentThread().getName()+"进入仓库,准备生产!");
            try {
                if(storageList.size()==MAX_SIZE) {
                    System.out.println("仓库已满!等待消费者消费");
                    Thread.sleep(1000);
                    full.await();//生产者线程加入线程等待池
                }
                if(storageList.size()<MAX_SIZE){
                    String name = "产品"+new Random().nextInt();
                    storageList.add(name);
                    System.out.println(Thread.currentThread().getName()+"往仓库中生产了一个产品!");
                }
                Thread.sleep(1000);
                empty.signalAll();//唤醒消费者线程

            }catch(InterruptedException ie) {
                System.out.println("中断异常");
                ie.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
    }

    @Override
    public void run() {
        while(true) {
            produce();
        }
    }
}

//消费者线程
private class Customer implements Runnable{

    //消费方法,需同步
    private void consume() {
        if(lock.tryLock()) {
            System.out.println(Thread.currentThread().getName()+"进入仓库,准备消费!");
            try {
                if(storageList.size()==ZERO) {
                    System.out.println("仓库已空!等待生产者生产");
                    Thread.sleep(1000);
                    empty.await();//消费者线程加入线程等待池
                }
                if(storageList.size()!=ZERO) {
                    System.out.println(Thread.currentThread().getName()+"从仓库取得产品:"+storageList.remove(0));
                }

                Thread.sleep(1000);
                full.signalAll();//唤醒生产者线程
            }catch(InterruptedException ie) {
                System.out.println("中断异常");
                ie.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
    }

    @Override
    public void run() {
        while(true) {
            consume();
        }
    }

}

//启动生产者和消费者线程
public void start() {
    for(int i=1;i<5;i++) {
        //new Thread(new Producer()).start();
        //new Thread(new Customer()).start();
        pool.execute(new Producer());
        pool.execute(new Customer());
    }

}

public static void main(String[] args) {
    ProducerCustomerWithLock pc = new ProducerCustomerWithLock();
    pc.start();
}

}
3.BlockingQueue实现的生产者和消费者
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
* BlockingQueue实现的生产者和消费者
*
*/
public class ProducerCustomerWithBlockingQueue {

Executor pool = Executors.newFixedThreadPool(10);

//仓库
private BlockingQueue<String> storageQueue = new LinkedBlockingQueue<String>(5);

//仓库容量
private int MAX_SIZE = 3;

//仓库为空
private int ZERO = 0;



//生产者线程
private class Producer implements Runnable{

    //生产方法,需同步
    private void produce(){
        try {
            System.out.println(Thread.currentThread().getName()+"进入仓库,准备生产!");
            if(storageQueue.size()==MAX_SIZE) {
                System.out.println("仓库已满!等待消费者消费");
                Thread.sleep(1000);
            }
            if(storageQueue.size()<=MAX_SIZE) {
                String product = "产品"+new Random().nextInt();
                storageQueue.put(product);
                System.out.println(Thread.currentThread().getName()+"往仓库中生产了一个产品!");
            }
            Thread.sleep(1000);
        }catch(InterruptedException ie) {
            System.out.println("中断异常");
            ie.printStackTrace();
        }
    }

    @Override
    public void run() {
        while(true) {
            produce();
        }
    }
}

//消费者线程
private class Customer implements Runnable{

    //消费方法,需同步
    private void consume() {
        try {
            System.out.println(Thread.currentThread().getName()+"进入仓库,准备消费!");
            if(storageQueue.size()==ZERO) {
                System.out.println("仓库已空!等待生产者生产");
                Thread.sleep(1000);
            }
            if(storageQueue.size()!=ZERO) {
                System.out.println(Thread.currentThread().getName()+"从仓库取得产品:"+storageQueue.take());
            }
            Thread.sleep(1000);
        }catch(InterruptedException ie) {
            System.out.println("中断异常");
            ie.printStackTrace();
        }
    }

    @Override
    public void run() {
        while(true) {
            consume();
        }
    }

}

//启动生产者和消费者线程
public void start() {
    for(int i=1;i<5;i++) {
        //new Thread(new Producer()).start();
        ///new Thread(new Customer()).start();
        pool.execute(new Producer());
        pool.execute(new Customer());
    }

}

public static void main(String[] args) {
    ProducerCustomerWithBlockingQueue pc = new ProducerCustomerWithBlockingQueue();
    pc.start();
}

}

1. 目的: 调试、修改、运行模拟程序,通过形象化的状态显示,使学生理解进程的概念,了解同步和通信的过程,掌握进程通信和同步的机制,特别是利用缓冲区进行同步和通信的过程。通过补充新功能,使学生能灵活运用相关知识,培养创新能力。 2. 内容及要求: 1) 调试、运行模拟程序。 2) 发现并修改程序中不完善的地方。 3) 修改程序,使用随机数控制创建生产者消费者的过程。 4) 在原来程序的基础上,加入缓冲区的写互斥控制功能,模拟多个进程存取一个公共缓冲区,当有进程正在写缓冲区时,其他要访问该缓冲区的进程必须等待,当有进程正在读取缓冲区时,其他要求读取的进程可以访问,而要求写的进程应该等待。 5) 完成1)、2)、3)功能的,得基本分,完成4)功能的加2分,有其它功能改进的再加2分 3. 程序说明:   本程序是模拟两个进程,生产者(producer)和消费者(Consumer)工作。生产者每次产生一个数据,送入缓冲区中。消费者每次从缓冲区中取走一个数据。缓冲区可以容纳8个数据。因为缓冲区是有限的,因此当其满了时生产者进程应该等待,而空时,消费者进程应该等待;当生产者向缓冲区放入了一个数据,应唤醒正在等待的消费者进程,同样,当消费者取走一个数据后,应唤醒正在等待的生产者进程。就是生产者消费者之间的同步。   每次写入和读出数据时,都将读和写指针加一。当读写指针同样时,又一起退回起点。当写指针指向最后时,生产者就等待。当读指针为零时,再次要读取的消费者也应该等待。 为简单起见,每次产生的数据为0-99的整数,从0开始,顺序递增。两个进程的调度是通过运行者使用键盘来实现的。 4. 程序使用的数据结构 进程控制块:包括进程名,进程状态和执行次数。 缓冲区:一个整数数组。 缓冲区说明块:包括类型,读指针,写指针,读等待指针和写等待指针。 5. 程序使用说明   启动程序后,如果使用'p'键则运行一次生产者进程,使用'c'键则运行一次消费者进程。通过屏幕可以观察到两个进程的状态和缓冲区变化的情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值