线程生产者与消费者

package cn.itcast.thread;
/*
 线程通讯:  一个A线程完成了当前的任务时,要通知另外B线程去做另外事情。
 
生产者与消费者。

问题一:价格错乱问题。(线程安全问题)

问题: 目前要不就是生成一大批的产品,要不消费一大批的产品

要求的效果: 生产一个消费一个。

线程通讯相关方法:
     wait()       如果一个线程调用了wait方法,那么该线程会进入以锁对象的监听器作为标识符建立的线程池中等待。  等待状态先的线程会释放锁对象。
     notify()      如果一个线程调用了notify方法,那么会唤醒以锁对象的监听器建立的线程池中等待线程的其中一个。    
     notifyAll()  唤醒以锁对象的监听器建立线程池中 的所有等待线程。

线程通讯要注意的事项:
    1. wait() ,notify() , notifyAll() 这三个方法都是属于Object类的,并不是属于Thread类的。
    2. 调用wait() ,notify() , notifyAll() 这三个方法都必须要在同步函数或者是同步代码块中调用,否则报错。
    3. 调用wait() ,notify() , notifyAll() 这三个方法都必须要由锁对象调用。
    
 */

//产品类
class Product{
    
    String name;
    
    int price;
    
    boolean  flag = false;     //是否生产完毕的标识     false为没有生产完成  ,true 生产完毕。
}

//生产者
class  Producer extends Thread{
    
    Product p;
    
    public Producer(Product p){
        this.p = p;
    }
    
    
    @Override
    public void run() {
        int i = 0;
        while(true){
            synchronized (p) {
                if(p.flag==false){
                    if(i%2==0){
                        p.name = "自行车";
                        p.price = 300;
                    }else{
                        p.name = "摩托车";   //摩托车  300
                        p.price = 4000;
                    }
                    System.out.println("生产者生成了"+p.name+" 价格是:"+ p.price);
                    //产品已经生成完毕,就应该唤醒消费者去消费。
                    p.flag   =true;
                    i++;
                    p.notify();
                }else{
                    try {
                        p.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                }
            }
            
        }
    }
}

//消费者
class Customer extends Thread{
    
    Product p;
    
    public Customer(Product p) {
        this.p = p;
    }
    
    @Override
    public void run() {
        while(true){
            synchronized (p) {    
                if(p.flag==true){
                    System.out.println("消费者消费了:"+ p.name+" 价格:"+ p.price);
                    p.flag = false;
                    p.notify();
                }else{
                    try {
                        p.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
}

public class Demo3 {
    
    public static void main(String[] args) {
        //创建一个产品对象
        Product p = new Product();
        //创建一个生产者对象
        Producer producer = new Producer(p);
        //创建消费者对象
        Customer customer = new Customer(p);
        //启动线程
        producer.start();
        customer.start();
        
        
    }

}

时间: 2024-08-09 08:41:57

线程生产者与消费者的相关文章

java线程 生产者与消费者

package org.rui.thread.block; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 生产者与消费者 * 餐馆 * * @author lenovo * */ public class Restaurant { //Restaurant r=new Restaurant

Java---20---多线程:生产者和消费者2(JDK1.5升级版)

此篇文章写的是JDK1.5升级版的生产者和消费者. Java 升级之后的解决方法: Lock java.util.concurrent.locks 接口 Lock 所有已知实现类: ReentrantLock,ReentrantReadWriteLock.ReadLock,ReentrantReadWriteLock.WriteLock public interface Lock Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作.此实现允许更灵活的结构,可

Java线程学习整理--4---一个简单的生产者、消费者模型

 1.简单的小例子: 下面这个例子主要观察的是: 一个对象的wait()和notify()使用情况! 当一个对象调用了wait(),那么当前掌握该对象锁标记的线程,就会让出CPU的使用权,转而进入该对象的等待池中等待唤醒,这里说明一下,每一个对象都有一个独立的等待池和锁池! 等待池:上述的wait()后的线程会进入等待池中,处于下图线程声明周期(简单示意图) 中的这个状态,等待池中的线程任然具有对象的锁标记,但是处于休眠状态,不是可运行状态! 当该对象调用notify方法之后,就会在等待池中系统

linux中的线程同步:生产者、消费者问题

#include <stdio.h> #include <semaphore.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #define BUFFER_COUNT 5 int Buffer[BUFFER_COUNT]; //指针数组 int front = 0; int tail = 0; sem_t SemProd; sem_t SemCon; void* pr

多线程-线程间通信-多生产者多消费者示例

1.多线程-线程间通信-多生产者多消费者问题 多生产者和多消费者.等待唤醒机制. 产生了两个问题: 1.出现了多次连续生产,未消费,或者一个商品被消费多次. 解决:必须要--------每一个被唤醒的线程判断一次标记,所以将if判断改为while判断. 2.出现了死锁. 本方唤醒了本方,导致了所有的线程都等待了. 解决方式就是:唤醒所有等待的线程.这样既唤醒了本方也唤醒对方. 虽然解决了多生产消费的问题,但是有些低效. 解决方法一: 唤醒所有等待的线程 class Resource{     p

生产者与消费者模式(线程的同步与互斥)

死锁产生的四个条件: 1.互斥使用(资源独占) 一个资源每次只能给一个进程使用 .2.不可强占(不可剥夺) 资源申请者不能强行的从资源占有者手中夺取资源,资源只能由占有者自愿释放 .3.请求和保持(部分分配,占有申请) 一个进程在申请新的资源的同时保持对原有资源的占有(只有这样才是动态申请,动态分配) .4.循环等待 存在一个进程等待队列 {P1 , P2 , - , Pn}, 其中P1等待P2占有的资源,P2等待P3占有的资源,-,Pn等待P1占有的资源,形成一个进程等待环路 生产者:生产数据

C# 线程(四):生产者和消费者

From : http://kb.cnblogs.com/page/42530/ 前面说过,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生. C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待.在C#中,关键字lock定义如下: lock(expres

JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917 我们来继续学习多线程 Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock Lock void lock():获取锁 v

Java---19---多线程:生产者和消费者

生产者和消费者问题是多线程通信的经典问题.这类问题描述了这样一种情况:假设有一个仓库,用来存储产品,有生产者负责生产产品,有消费者负责消费.生产者生产的产品存放在仓库之中,消费者从仓库之中取出产品.显然这是一个同步问题,生产者和消费者共享同一资源,并且生产者和消费者之间彼此依赖,互为条件向前推进.那么,该如何编写代码来实现呢? class Resource { private String name; private String sex; private boolean flag = fals