`

用并发包中的重入锁实现生产消费模型

阅读更多

传统的生产消费模型,实际上是通过一个条件来调节生产者和消费者线程的唤醒或者等待,这样做的坏处是,不该被唤醒的线程也会被唤醒,这样对多线程编程来说,会引起线程无谓切换,在Java5中的并发编程包中,有重入锁实现了多条件的锁来实现生产者线程只会唤醒消费者线程,而不会唤醒其它的生产者线程,这样就适当地减少了线程的切换开销。

 

 

 

源代码如下:

 

 

1.仓库

 

package readwritelock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;

public class Godown {
    public static final int max_size = 100; // 最大库存量
    public Lock lock = new ReentrantLock();
    Condition full = lock.newCondition();
    Condition empty = lock.newCondition();

    public Object o = new Object();
    public int curnum; // 当前库存量

    Godown() {
    }

    Godown(int curnum) {
        this.curnum = curnum;

    }

    /**
     * 生产指定数量的产品
     *
     * @param neednum
     */
    public void produce(int neednum) {
        lock.lock();
        try {
            // 测试是否需要生产
            while (neednum + curnum > max_size) {
                System.out.println("要生产的产品数量" + neednum + "超过剩余库存量"
                        + (max_size - curnum) + ",暂时不能执行生产任务!");
                try {
                    // 当前的生产线程等待
                    full.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 满足生产条件,则进行生产,这里简单的更改当前库存量
            curnum += neednum;
            System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum);
            // 唤醒在此对象监视器上等待的所有线程
            empty.signalAll();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 消费指定数量的产品
     *
     * @param neednum
     */
    public synchronized void consume(int neednum) {
        lock.lock();
        try {
            // 测试是否可消费
            while (curnum < neednum) {
                try {
                    // 当前的消费线程等待
                    empty.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 满足消费条件,则进行消费,这里简单的更改当前库存量
            curnum -= neednum;
            System.out.println("已经消费了" + neednum + "个产品,现仓储量为" + curnum);
            // 唤醒在此对象监视器上等待的所有线程
            full.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

 

2.生产者

 

package readwritelock;

public class Producer extends Thread {
    private int neednum;                //生产产品的数量
    private Godown godown;            //仓库

    Producer(int neednum, Godown godown) {
            this.neednum = neednum;
            this.godown = godown;
    }

    public void run() {
            //生产指定数量的产品
            godown.produce(neednum);
    }

}

 

3.消费者

package readwritelock;

public class Consumer extends Thread {
    private int neednum;                //生产产品的数量
    private Godown godown;            //仓库

    Consumer(int neednum, Godown godown) {
            this.neednum = neednum;
            this.godown = godown;
    }

    public void run() {
            //消费指定数量的产品
            godown.consume(neednum);
    }
}

 

4.测试类

 

package readwritelock;

public class Test {
     public static void main(String[] args) {
         Godown godown = new Godown(30);
         Consumer c1 = new Consumer(50, godown);
         Consumer c2 = new Consumer(20, godown);
         Consumer c3 = new Consumer(30, godown);
         Producer p1 = new Producer(10, godown);
         Producer p2 = new Producer(10, godown);
         Producer p3 = new Producer(10, godown);
         Producer p4 = new Producer(10, godown);
         Producer p5 = new Producer(10, godown);
         Producer p6 = new Producer(10, godown);
         Producer p7 = new Producer(80, godown);

         c1.start();
         c2.start();
         c3.start();
         p1.start();
         p2.start();
         p3.start();
         p4.start();
         p5.start();
         p6.start();
         p7.start();
 }
}

分享到:
评论

相关推荐

    java编程的生产者消费者同步锁线程测试

    为此,我们可以使用`BlockingQueue`接口,它是Java并发包中提供的一个阻塞队列,内置了线程安全的生产和消费操作。例如,`ArrayBlockingQueue`是一个有界的阻塞队列,可以防止生产者过度生产。 线程间的通信和协作...

    JAVA高并发包介绍

    它使用原子引用更新来保证操作的线程安全性,适合在多生产者和多消费者环境中使用。 ConcurrentLinkedQueue的结构预览与普通链表相似,但它具有无界的特性,这意味着它可以持续地添加元素而不受容量限制。它的常用...

    java5 并发包 (concurrent)思维导图

    Java 5并发包(`java.util.concurrent`,简称`Concurrent`包)是Java平台中用于多线程编程的重要组成部分,它提供了丰富的并发工具类,极大地简化了在多线程环境下的编程工作。这个包的设计目标是提高并发性能,减少...

    java多线程(生产者与消费者)

    4. **阻塞队列(BlockingQueue)**:Java并发包(java.util.concurrent)中的阻塞队列是实现生产者消费者模式的理想选择。它们在内部已经处理了线程同步和等待,提供了一种高效且安全的共享数据方式。例如,`put()`...

    java 生产者与消费者

    为了实现生产者与消费者的模型,可以使用`BlockingQueue`(阻塞队列),它是Java并发包`java.util.concurrent`中的重要组件。`BlockingQueue`在满时会阻止生产者继续插入元素,在空时阻止消费者继续取出元素,实现了...

    生产者消费者同步

    在生产者消费者模型中,通常会有一个共享的数据容器,比如一个队列。生产者线程负责将数据放入队列,而消费者线程则负责从队列中取出数据进行处理。为了确保线程安全,我们需要在生产者向队列添加元素和消费者从队列...

    Java并发编程实践-03章-使用JDK并发包构建程序1

    总之,JDK并发包为开发者提供了丰富的工具来处理并发问题,包括原子量、并发集合、同步器和显式锁等,这些工具的合理使用能够显著提高并发程序的性能和可维护性。在实际开发中,理解并熟练掌握这些工具是构建高效...

    java生产者消费者问题

    4. **消费者线程**:消费者线程则使用`take()`方法从队列中取出元素,当队列为空时,消费者线程会被阻塞,直到有新的元素被生产者线程放入队列。 5. **示例代码**: ```java import java.util.concurrent....

    基于JAVA线程机制研究生产者-消费者问题.zip

    2. BlockingQueue:Java并发包(java.util.concurrent)中的BlockingQueue接口提供了一种更安全、更高效的方式来处理生产者-消费者问题。它是一个线程安全的数据结构,内部已经实现了线程同步和等待通知机制。生产者...

    精选_毕业设计_基于JAVA的生产者消费者问题_完整源码

    在这个毕业设计中,开发者可能使用了Java的阻塞队列(BlockingQueue)接口,如ArrayBlockingQueue或LinkedBlockingQueue,这些队列内置了线程安全的生产和消费操作,可以有效地实现生产者和消费者之间的同步。...

    Java并发编程中的生产者与消费者模型简述

    使用`BlockingQueue`,生产者可以直接将产品放入队列,而消费者则可以从队列中取出产品,无需手动管理线程的等待和唤醒。这种实现方式不仅简化了代码,还提高了系统的可扩展性和性能。 总结来说,Java并发编程中的...

    juc详解juc详解juc详解juc详解juc详解juc详解juc详解

    - `LinkedBlockingQueue`:有界的阻塞队列,适用于生产者-消费者模型。 4. **同步器**: - `CountDownLatch`:计数器,用于等待多个线程完成操作后再继续执行。 - `CyclicBarrier`:回环栅栏,允许一组线程等待...

    JavaLock与Condition的理解Reentran

    ReentrantLock是Java并发包java.util.concurrent.locks中的一个类,它是可重入的互斥锁,具备了synchronized的同步特性,同时提供了更多的高级功能。可重入性意味着一个线程可以获取同一锁多次而不被阻塞,这对于...

    java并发编程从入门到精通

    例如,生产者-消费者模式是多线程编程中经常使用的模式,它通过使用阻塞队列(BlockingQueue)来协调生产者和消费者之间的操作。还有诸如Future模式、读写模式等,这些模式不仅能够解决特定问题,还可以提高代码的...

    提升Java的锁性能Java开发Java经验技巧共5页.p

    - **生产者-消费者模式**:`BlockingQueue`可以实现线程间的解耦,高效地传递数据。 - **工作窃取算法**:线程从其他队列偷取任务执行,避免线程饥饿。 8. **Java内存模型(JMM)** - 理解JMM对可见性和有序性的...

    Java并发编程(21)并发新特性-阻塞队列和阻塞栈(含代

    这些数据结构源自Java的并发包`java.util.concurrent`,是实现并发设计模式如生产者消费者模型的基础。 **阻塞队列(BlockingQueue)** 阻塞队列是一种特殊的队列,当队列为空时,从队列中获取元素的操作将会被...

    Java多线程设计模式(带源码)

    1. 生产者消费者模式:通过共享队列实现生产者线程和消费者线程之间的通信。生产者负责生成数据,将其放入队列;消费者则从队列中取出数据进行处理。`BlockingQueue`接口是Java并发包中实现该模式的关键类。 2. ...

    Java高并发程序设计视频

    内置锁通过监视器锁实现,保证了同一时间只有一个线程执行特定代码块;显式锁提供更细粒度的控制,如可重入锁、公平锁和读写锁。 3. 并行模式: - 并行模式是解决并发问题的常用设计模式,如生产者-消费者模式、...

    Java 并发编程硬核资料.pdf

    锁的机制则主要涉及到不同类型的锁(如读写锁、可重入锁等)的使用和场景,以及如何在保证并发安全的同时,提高系统的执行效率。Java内存模型是描述多线程环境下,线程间共享变量如何同步的模型,涉及到happens-...

    java 提供消息队列的使用

    阻塞队列是Java并发包`java.util.concurrent`中的一个数据结构,它结合了队列和锁的概念,常用于构建高效的消息传递机制。在生产者-消费者问题中,阻塞队列能自动同步生产者和消费者的动作,当队列满时,生产者会被...

Global site tag (gtag.js) - Google Analytics