java基础——线程通信机制,生产者消费者

package communication;

/*
使用两个线程1,2交替打印1-100

线程通信方法:
    1.wait():一旦执行此方法,当前线程进入阻塞态,并释放锁
    2.notify():会唤醒被wait的一个线程,如果有多个线程wait,则唤醒优先级高的
    3.notifyAll():唤醒所有被wait的线程

说明:
    1.wait(),notify(),notifyAll()使用在同步代码块或同步方法中,不能用在lock方法中
    2.这三个方法的调用者必须是同步代码块或同步方法中的锁对象(同步监视器)
        否则会出现异常
    3.这三个方法定义在java.lang.Object 中

sleep()和wait()的不同
1.声明位置不同,Thread类汇总声明sleep,Object中声明wait
2.sleep可以在任何需要场景调用,wait必须由同步监视器调用
3.sleep后线程不释放锁,wait线程释放锁

@author zsben
@create 2020-01-05 12:05
*/

import java.util.concurrent.locks.ReentrantLock;

class Number implements Runnable{

    private int number = 100;
    private ReentrantLock lock = new ReentrantLock(false);

    @Override
    public void run() {
        while(true){
            synchronized (this){
                //唤醒所有线程线程
                notifyAll();

                if(number > 0){
                    try {
                        //线程会阻塞,但是不会释放锁对象
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    try {
                        //使该线程进入阻塞态,同时释放持有的锁对象
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName()+": "+number);
                    number--;
                }else break;
            }
        }
    }
}

public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);
        Thread t3 = new Thread(number);

        t1.start();
        t2.start();
        t3.start();
    }
}

下面是生产者消费者的例子

package communication;

/*
生产者消费者问题实现

@author zsben
@create 2020-01-05 13:55
*/

class Clerk{

    private int productCount = 0;

    //生产产品:原子操作
    public synchronized void produceProduct() {

        if(productCount < 20){
            productCount++;
            System.out.println(Thread.currentThread().getName()+"生产产品"+productCount);
            notify();
        }
        else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //消费产品:原子操作
    public synchronized void consumerProduct() {
        if(productCount > 0){
            System.out.println(Thread.currentThread().getName()+"消费产品"+productCount);
            productCount--;
            notify();
        }
        else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Producer extends Thread{
    private Clerk clerk;

    public Producer(Clerk clerk) {//生产者
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(getName()+": 开始生产产品...");

        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            clerk.produceProduct();
        }
    }
}

class Consumer extends Thread{//消费者
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(getName()+": 开始消费产品...");

        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            clerk.consumerProduct();
        }
    }
}

public class ProductTest {

    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Producer p1 = new Producer(clerk);
        p1.setName("生产者1");
        Consumer c1 = new Consumer(clerk);
        c1.setName("消费者1");

        p1.start();
        c1.start();
    }
}

原文地址:https://www.cnblogs.com/zsben991126/p/12153090.html

时间: 2024-10-11 17:17:42

java基础——线程通信机制,生产者消费者的相关文章

Condition线程通信_生产者消费者案例

①Condition 接口描述了可能会与锁有关联的条件变量. 这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能. 需要特别指出的是,单个 Lock 可能与多个 Condition 对象关 联. 为了避免兼容性问题,Condition 方法的名称与对应的 Object 版 本中的不同.② 在 Condition 对象中,与 wait.notify 和 notifyAll 方法对应的分别是 await.signal 和 signalAll.③ Condi

11.9-全栈Java笔记: 线程并发协作(生产者/消费者模式)

多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型"生产者消费者模式". 什么是生产者? 生产者指的是负责生产数据的模块(这里模块可能是:方法.对象.线程.进程). 什么是消费者? 消费者指的是负责处理数据的模块(这里模块可能是:方法.对象.线程.进程). 什么是缓冲区? 消费者不能直接使用生产者的数据,它们之间有个"缓冲区".生产者将生产好的数据放入"缓冲区",消费者从"缓冲区"

线程通信之生产者消费者阻塞队列版

class MyResource { private volatile boolean FLAG = true; //默认开启,进行生产+消费 private AtomicInteger atomicInteger = new AtomicInteger(); BlockingQueue<String> blockingQueue = null; public MyResource(BlockingQueue<String> blockingQueue) { this.blocki

JAVA多线程提高二:传统线程的互斥与同步&amp;传统线程通信机制

本文主要是回顾线程之间互斥和同步,以及线程之间通信,在最开始没有juc并发包情况下,如何实现的,也就是我们传统的方式如何来实现的,回顾知识是为了后面的提高作准备. 一.线程的互斥 为什么会有线程的互斥?可以想银行取款的问题,如果不做监控,多个人同时针对一个存折取钱的时候就会出现钱不对的问题,下面我们通过两个例子来分析一下线程的互斥问题以及为什么会产生这个线程? 例子1:一个人生产信息,一个人消费信息 面向对象的思想:类 信息类 生产者 消费者 public class TriditionalTh

Linux线程编程之生产者消费者问题

前言 本文基于顺序循环队列,给出Linux生产者/消费者问题的多线程示例,并讨论编程时需要注意的事项.文中涉及的代码运行环境如下: 本文假定读者已具备线程同步的基础知识. 一  顺序表循环队列 1.1 顺序循环队列定义 队列是一种运算受限的先进先出线性表,仅允许在队尾插入(入队),在队首删除(出队).新元素入队后成为新的队尾元素,元素出队后其后继元素就成为队首元素. 队列的顺序存储结构使用一个数组和两个整型变量实现,其结构如下: 1 struct Queue{ 2 ElemType elem[M

Java基础——线程总结

Java基础--线程总结 一.线程是什么? 线程:一个程序里不同的执行路径. 二.如何创建线程? 两种方法创建线程: 第一种 (1)定义具体功能类实现Runnable接口,可以多次调用而实现数据共享 (2)Thread myThread = new Thread(-)          //参数为Runnable接口类型 (3)Runnable中只有一个方法 public void run(){--} //用以定义线程运行体 第二种 (1)定义一个Thread的子类并重写run()方法 clas

线程通信(生产者与消费者问题)

1.线程通信的必要性 多线程不仅共享资源,而且相互牵制向前运行. 2.线程通信的方法(都是在Object中定义) 3个方法: 1)    wait() 可运行转入阻塞状态,放锁 2)    notify() 阻塞转入可运行状态,获得锁 3)    notifyAll() 所有调用wait方法而被挂起的线程重新启动,有个条件:wait与notifyAll必须是属于同一个对象 必须在同步方法或同步代码块中使用 3.共享资源类(仓库) 注:共享资源(产品),牵制信息(产品有无)  package co

线程安全的生产者消费者四种实现方法

问题描述 在IT技术面试过程中,我们经常会遇到生产者消费者问题(Producer-consumer problem), 这是多线程并发协作问题的经典案例.场景中包含三个对象,生产者(Producer),消费者(Consumer)以及一个固定大小的缓冲区(Buffer).生产者的主要作用是不断生成数据放到缓冲区,消费者则从缓冲区不断消耗数据.该问题的关键是如何线程安全的操作共享数据块,保证生产者线程和消费者线程可以正确的更新数据块,主要考虑 1. 生产者不会在缓冲区满时加入数据. 2. 消费者应当

Java多线程之并发协作生产者消费者设计模式

两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标记或加锁机制 wait() / nofity() 方法是基类Object的两个方法,也就意味着所有Java类都会拥有这两个方法,这样,我们就可以为任何对象实现同步机制. wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等等状态,让其他线程执行. notify