Java多线程-生产者消费者例子-使用Lock实现

简介: Java多线程-生产者消费者例子-使用Lock实现 import java.util.LinkedList; import java.util.List; import java.util.concurrent.

Java多线程-生产者消费者例子-使用Lock实现

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

/**
 * Created by wisgood .
 */
public class ProducerConsumerWithLockDemo {
    public static void main(String[] args) {
        ProductFactoryWithLock productFactory = new ProductFactoryWithLock(10);
        new Thread(new ProducerWithLock(productFactory), "1号生产者").start();
        new Thread(new ConsumerWithLock(productFactory), "1号消费者").start();
        new Thread(new ConsumerWithLock(productFactory), "2号消费者").start();
    }
}

class ProductFactoryWithLock {
    private List<String> products;
    private int capacity = 0;
    private Lock lock = new ReentrantLock();
    private Condition canProduce = lock.newCondition();
    private Condition canConsume = lock.newCondition();
    public ProductFactoryWithLock(int capacity) {
        this.capacity = capacity;
        products = new LinkedList<>();
    }

    // 生产产品
    public void produce(String product) {
        lock.lock();
        try {
            while (capacity == products.size()) {
                //打日志的目的是更好的观察消费者和生产者状态
                System.out.println("警告:线程(" + Thread.currentThread().getName() + ")准备生产产品,但产品池已满");
                try {
                    canProduce.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            products.add(product);
            System.out.println("线程(" + Thread.currentThread().getName() + ")生产了一件产品:" + product + ";当前剩余商品" + products.size() + "个");
            canConsume.signal();
        } finally {
            lock.unlock();
        }

    }

    // 消费产品
    public synchronized String consume() {
        lock.lock();
        try{
            while (products.size() == 0) {
                try {
                    //打日志的目的是更好的观察消费者和生产者状态
                    System.out.println("警告:线程(" + Thread.currentThread().getName() + ")准备消费产品,但当前没有产品");
                    canConsume.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            String product = products.remove(0);
            System.out.println("线程(" + Thread.currentThread().getName() + ")消费了一件产品:" + product + ";当前剩余商品" + products.size() + "个");
            canProduce.signal();
            return product;
        }finally {
            lock.unlock();
        }
    }
}

// 生产者
class ProducerWithLock implements Runnable {
    private ProductFactoryWithLock productFactory;
    public ProducerWithLock(ProductFactoryWithLock productFactory) {
        this.productFactory = productFactory;
    }
    public void run() {
        int i = 0;
        while (true) {
            productFactory.produce(String.valueOf(i));
            i++;
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 消费者
class ConsumerWithLock implements Runnable {
    private ProductFactoryWithLock productFactory;
    public ConsumerWithLock(ProductFactoryWithLock productFactory) {
        this.productFactory = productFactory;
    }

    public void run() {
        while (true) {
            productFactory.consume();
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

输出结果

线程(1号生产者)生产了一件产品:0;当前剩余商品1个
线程(1号消费者)消费了一件产品:0;当前剩余商品0个
警告:线程(2号消费者)准备消费产品,但当前没有产品
线程(1号生产者)生产了一件产品:1;当前剩余商品1个
线程(2号消费者)消费了一件产品:1;当前剩余商品0个
线程(1号生产者)生产了一件产品:2;当前剩余商品1个
线程(1号生产者)生产了一件产品:3;当前剩余商品2个
线程(1号生产者)生产了一件产品:4;当前剩余商品3个
线程(1号生产者)生产了一件产品:5;当前剩余商品4个
线程(1号生产者)生产了一件产品:6;当前剩余商品5个
线程(1号生产者)生产了一件产品:7;当前剩余商品6个
线程(1号生产者)生产了一件产品:8;当前剩余商品7个
线程(1号生产者)生产了一件产品:9;当前剩余商品8个
线程(1号生产者)生产了一件产品:10;当前剩余商品9个
线程(1号生产者)生产了一件产品:11;当前剩余商品10个
警告:线程(1号生产者)准备生产产品,但产品池已满
线程(1号消费者)消费了一件产品:2;当前剩余商品9个
线程(1号生产者)生产了一件产品:12;当前剩余商品10个
线程(2号消费者)消费了一件产品:3;当前剩余商品9个
线程(1号生产者)生产了一件产品:13;当前剩余商品10个
警告:线程(1号生产者)准备生产产品,但产品池已满
线程(1号消费者)消费了一件产品:4;当前剩余商品9个
线程(1号生产者)生产了一件产品:14;当前剩余商品10个
线程(2号消费者)消费了一件产品:5;当前剩余商品9个
线程(1号生产者)生产了一件产品:15;当前剩余商品10个
警告:线程(1号生产者)准备生产产品,但产品池已满
线程(1号消费者)消费了一件产品:6;当前剩余商品9个
线程(1号生产者)生产了一件产品:16;当前剩余商品10个
警告:线程(1号生产者)准备生产产品,但产品池已满
线程(2号消费者)消费了一件产品:7;当前剩余商品9个
线程(1号生产者)生产了一件产品:17;当前剩余商品10个
原文地址http://www.bieryun.com/2508.html
相关文章
|
3天前
|
安全 Java 调度
Java线程:深入理解与实战应用
Java线程:深入理解与实战应用
21 0
|
1天前
|
消息中间件 缓存 NoSQL
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
|
1天前
|
消息中间件 存储 Java
Java与Go的生产者消费者模型比较
【4月更文挑战第20天】
8 1
|
1天前
|
数据采集 存储 Java
高德地图爬虫实践:Java多线程并发处理策略
高德地图爬虫实践:Java多线程并发处理策略
|
2天前
|
缓存 Java
【Java基础】简说多线程(上)
【Java基础】简说多线程(上)
6 0
|
2天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
2天前
|
安全 Java 编译器
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
本文简要介绍了Java中的`synchronized`关键字,它是用于保证多线程环境下的同步,解决原子性、可见性和顺序性问题。从JDK1.6开始,synchronized进行了优化,性能得到提升,现在仍可在项目中使用。synchronized有三种用法:修饰实例方法、静态方法和代码块。文章还讨论了synchronized修饰代码块的锁对象、静态与非静态方法调用的互斥性,以及构造方法不能被同步修饰。此外,通过反汇编展示了`synchronized`在方法和代码块上的底层实现,涉及ObjectMonitor和monitorenter/monitorexit指令。
15 0
|
2天前
|
监控 安全 Java
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
10 2
|
2天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
28 1
|
2天前
|
安全 Java
Java基础教程(15)-多线程基础
【4月更文挑战第15天】Java内置多线程支持,通过Thread类或Runnable接口实现。线程状态包括New、Runnable、Blocked、Waiting、Timed Waiting和Terminated。启动线程调用start(),中断线程用interrupt(),同步用synchronized关键字。线程安全包如java.util.concurrent提供并发集合和原子操作。线程池如ExecutorService简化任务管理,Callable接口允许返回值,Future配合获取异步结果。Java 8引入CompletableFuture支持回调。

热门文章

最新文章