JAVA生产者消费者(线程同步)代码学习示例_java

一、问题描述

生产者消费者问题是一个典型的线程同步问题。生产者生产商品放到容器中,容器有一定的容量(只能顺序放,先放后拿),消费者消费商品,当容器满了后,生产者等待,当容器为空时,消费者等待。当生产者将商品放入容器后,通知消费者;当消费者拿走商品后,通知生产者。

二、解决方案

对容器资源加锁,当取得锁后,才能对互斥资源进行操作。

复制代码 代码如下:

public class ProducerConsumerTest {

    public static void main(String []args){
        Container con = new Container();
        Producer p = new Producer(con);
        Consumer c = new Consumer(con);
        new Thread(p).start();
        new Thread(c).start();
    }

}

class Goods{
    int id;
    public Goods(int id){
        this.id=id;
    }

    public String toString(){
        return "商品"+this.id;
    }
}

class Container{//容器采用栈,先进后出
    private int index = 0;
    Goods[] goods = new Goods[6];

    public synchronized void push(Goods good){
        while(index==goods.length){//当容器满了,生产者等待
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        goods[index]=good;
        index++;
        notifyAll();//当生产者放入商品后通知消费者
    }

    public synchronized Goods pop(){
        while(index==0){//当容器内没有商品是等待
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        index--;
        notifyAll();//当消费者消费了商品后通知生产者
        return goods[index];
    }
}

class Producer implements Runnable{

    Container con = new Container();
    public Producer(Container con){
        this.con=con;
    }

    public void run(){
        for(int i=0; i<20; i++){
            Goods good = new Goods(i);
            con.push(good);
            System.out.println("生产了:"+good);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

class Consumer implements Runnable{

    Container con = new Container();
    public Consumer(Container con){
        this.con=con;
    }

    public void run(){
        for(int i=0; i<20; i++){
            Goods good=con.pop();
            System.out.println("消费了:"+good);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

   
}

时间: 2024-10-06 05:11:29

JAVA生产者消费者(线程同步)代码学习示例_java的相关文章

java 生产者消费者问题 并发问题的解决(转)

引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品.互相等待,从而发生死锁. 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/

java 生产者消费者问题

引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品.互相等待,从而发生死锁. 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/

关于java 中的线程同步问题,求大神解释。

问题描述 关于java 中的线程同步问题,求大神解释. 对于一个已经继承了Runnable 接口的类来说,假设创建了一个它的实例为 account, 那么: for(int i=0;i<500;i++) { new Thread(account).start(); } 不会造成500个线程同步访问同一资源而引发冲突? 为什么: private ExecutorService executor = Executors.newCachedThreadPool(); //在线程池中为每个等待的任务创建

一个java生产者消费者代码的问题

问题描述 一个生产者消费者的代码,使用lock和condition实现.import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;//生产/消费者模式public class Basket {Lock lock = new ReentrantLock();// 产生Condition对象Cond

java tcp socket 线程同步

问题描述 代码功能:客户端输入三个整数,服务器端返回客户端这三个整数的和我的思路服务器端起两个线程,一个监听,一个向客户端写出数据的线程,当收到数据后,用notify()唤醒写出线程,但我下面的代码输出端一直wait在那里,notify()都没用,不能实现同步啊publicclassServer{/**Server*/publicstaticfinalintPORT=6666;privateServerSocketserver=null;privateSocketclient=null;priv

Java中的线程同步与ThreadLocal无锁化线程封闭实现_java

Synchronized关键字 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(

线程-同步代码块的问题。。。。。

问题描述 同步代码块的问题..... 数据库的几张表常用表的数据,我想写到几个静态变量中. 然后提供若干个get方法,同时还有一个set方法重置所有的静态变量. 请问如何能够在set重置方法没完成以前,让get方法的线程等待? 同时几个get方法又不能有相互影响. 就是set没完成,所有的get需要等待,但是不同的get之间没完成不需要等待. 来人啊... 解决方案 http://my.oschina.net/tinglanrmb32/blog/339661 解决方案二: http://blog

Java用GDAL读写shapefile的方法示例_java

GDAL介绍 GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库.它利用抽象数据模型来表达所支持的各种文件格式.它还有一系列命令行工具来进行数据转换和处理. GDAL官方网址:http://www.gdal.org/,它能支持当前流行的各种地图数据格式,包括栅格和矢量地图,具体参考官方网站.该库使用C/C++开发,在Java中使用需要自己编译,具体编译过程这里就不说了,下面来看看本文的主要内容吧. Java使用G

Java中终止线程的三种方法_java

Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit 这些终止线程运行的方法已经被废弃,使用它们是极端不安全的! 1.线程正常执行完毕,正常结束 也就是让run方法执行完毕,该线程就会正常结束. 但有时候线程是永远无法结束的,比如while(true). 2.监视某些条件,结束线程的不间断运行 需要while()循环在某以特定条件下退出,最直接的办法就是设一个boolean标志,并通过设置这个标志来控制循环