线程(生产者消费者问题)

windows下多线程(生产者消费者问题:3个生产者,一个消费者,4个缓冲区) 原作者提供源码为两种情况: 第一种:1生产者1消费者1缓冲区 第二种:1生产者 2消费者 4缓冲区 ========================下面为修改作者源码得到的 3个生产者1个消费者4个缓冲区的情况==================  //1生产者 2消费者 4缓冲区 #include #include #include //设置控制台输出颜 阅读详情

Thread 随堂笔记

线程:一个程序里的不同执行路径。

线程的启动:

       方法一:实现Runnable接口(该接口只有一个方法 run)

       方法二:从Thread继承

Thread中的sleep方法:在哪个线程中调用Thread.sleep();哪个线程休息

Thread中的Join方法:在哪个线程中调用join();就把调用该方法的对象加入到该线程。

Thread中的yield方法:高风亮节把自己的线程先休息一会,让其它线程执行,Thread.yield

Thread中的priority:setPriority, getPriority

线程同步:

关键字:synchronized   锁定当前对象(在什么地方加锁呢,在线程共用的资源上加锁。)

DeadLock现象 :有个两个对象o1,o2 ;两个线程t1,t2。线程t1锁住了o1,线程t1锁住                    了o2,当线程t1再锁住o2的时候它就能继续执行,当线程t2在锁住o1的时候它就 能继续执行。但是o2被t1锁住了,o1被t2锁住了。谁也得不到能让自己继续执行 的对象,所以就产生了死锁的现象。

wait与sleep的区别:

     线程wait时,线程进入等待状态,同时释放锁,如果没有人叫醒它,它就会一直在   wait。(注意,线程并没有死掉,而是wait)

     线程sleep时,线程进入睡眠状态,但是没有释放锁,这时显示不需要有人叫它就   会自己醒。

生产者消费者问题:介绍了wait()方法,notity()/notityAll()方法,的作用。

package com.liang.thread;

public class ProduerConsumer {
	public static void main(String[] args) {
		SyncStack ss = new SyncStack();
		Produer p = new Produer(ss);
		Consumer c = new Consumer(ss);
		Thread tp = new Thread(p);
		Thread tp2 = new Thread(p);
		Thread tc = new Thread(c);
		tp.start();
		tp2.start();
		tc.start();
		System.out.println(Thread.activeCount());  //返回当前线程的线程组中活动线程的数目
	}
}

class ManTou {
	private int id;
	
	public ManTou(int id) {
		this.id = id;
	}
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
}

class SyncStack {
	ManTou[] mts = new ManTou[6];
	int index = 0;
	public synchronized void push(ManTou mt) {   //把ManTou放进框子里
		while(index == mts.length) {
			try {
				this.wait();      //让当前线程进入等待状态
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();   //叫醒在当前对象上等待的线程(但是不能叫醒线程本身)
		mts[index++] = mt;
	}
	
	public synchronized ManTou pop() {   //把ManTou从框子里拿出来
		while(index == 0) {
			try {
				this.wait();    //让当前线程进入等待状态
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();   //叫醒在当前对象上等待的线程(但是不能叫醒线程本身)
		return mts[--index];
	}
	
}

class Produer implements Runnable{       //生产者
	private SyncStack ss;
	
	public Produer(SyncStack ss) {
		this.ss = ss;
	}
	
	@Override
	public void run() {
		for(int i=0; i<20; i++) {
			ManTou mt = new ManTou(i);
			ss.push(mt);
			System.out.println("生产了 :" + mt.getId());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}

class Consumer implements Runnable{   //消费者
	private SyncStack ss;
	
	public Consumer(SyncStack ss) {
		this.ss = ss;
	}

	@Override
	public void run() {
		for(int i=0; i<20; i++) {
			 System.out.println("消费了 :" + ss.pop().getId());
			 try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}


 

 

Wait 和notify机制:wait/notify  机制是为了避免轮询带来的性能损失。 
为了说清道理,我们用“图书馆借书”这个经典例子来作解释。 一本书同时只能借给一个人。现在有一本书, 图书馆已经把这本书借了张三。 在简单的synchrnozed 同步机制下,李四如果想借,先要去图书馆查看书有没有还回 来。李四是个心急的人,他每天都去图书馆查;而张三看书看得慢,过了半个月才把书还回来,结果李四在这半个 月里全都白跑了,浪费了不少交通车费 
而如果使用wait/notify机制,李四就不用白忙了。他第一次去图书馆时发现书已借走,就回家静静等待(wait);张 三把书还掉后,通知(notify)李四,李四去图书馆拿书即可。整个过程中,李四没有白跑,没浪费钱。 

    回到计算机世界: 
        书                                 --  临界资源,需互斥地访问 
        张三,李四                 --  两个竞争的线程 
        坐车去图书馆查书     --  轮询 
        车费                             --  CPU空间 
        等待                             --  wait 
        通知下一个借书者     --  notify 
 
    也就是说,若使用简单的synchonized机制实现互斥,会导致线程主动发起轮询,若N次轮询没有成功,就产生了N次的CPU空间浪费;如果加上了 wait/notify机制,就可以避免这些无谓的轮询,节省CPU的消耗。

 

补充:

wait与notify是java同步机制中重要的组成部分。结合与synchronized关键字使用,可以建立很多优秀的同步模型。
     synchronized(this){}等价与public synchronized void method(){.....}
     同步分为类级别和对象级别,分别对应着类锁和对象锁。类锁是每个类只有一个,如果static的方法被synchronized关键字修饰,则在这个方法被执行前必须获得类锁;对象锁类同。(static synchronized是类级别的,非static的synchronized和synchronized块都是对象级别的,即作用在同一new出来的对象上)
     首先,
调用一个Object的wait与notify/notifyAll的时候,必须保证调用代码对该Object是同步的,也就是说必须在作用等同于synchronized(obj){......}的内部才能够去调用obj的wait与notify/notifyAll三个方法,否则就会报错:
     java.lang.IllegalMonitorStateException: current thread not owner
     在调用wait的时候,线程自动释放其占有的对象锁,同时不会去申请对象锁。当线程被唤醒的时候,它才再次获得了去获得对象锁的权利。
     所以,notify与notifyAll没有太多的区别,只是notify仅唤醒一个线程并允许它去获得锁,notifyAll是唤醒所有等待这个对象的线程并允许它们去获得对象锁,只要是在synchronied块中的代码,没有对象锁是寸步难行的。其实唤醒一个线程就是重新允许这个线程去获得对象锁并向下运行。
       顺便说一下notifyall,虽然是对每个wait的对象都调用一次notify,但是这个还是有顺序的,每个对象都保存这一个等待对象链,调用的顺序就是这个链的顺序。其实启动等待对象链中各个线程的也是一个线程,在具体应用的时候,需要注意一下。

windows多线程(十) 生产者与消费者问题 一、概述 生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再... 阅读详情

相关推荐

c++多线程 (生产者消费者问题)

针对多线程中常见的生产者消费者问题,封装了一个类,和测试代码,方便日后直接套用。 具体来说就是多线程使用时候经常遇到的 一个线程取数据,一个处理数据,一个保存或传递数据。

何似莫相逢 6078

生产者消费者问题

1. 使用栈来存放数据 1.1 把栈改造为支持线程安全 1.2 把栈的边界操作进行处理,当栈里的数据是0的时候,访问pull的线程就会等待。 当栈里的数据是10的时候,访问push的线程就会等待 2. 提供一个生产者(Producer)线程类,生产随机大写字符压入到堆栈 3. 提供一个消费者(Consumer)线程类,从堆栈中弹出字符并打印到控制台 4. 提供一个测试类...

XSG的博客 605

多线程代码实例

生产消费管理系统,采用多线程实现。在程序整个运行过程中,存在1个控制线程、1个生产者线程、以及若干个消费者线程。使用POSIX标准的互斥量、条件变量等进行共享资源的保护。

二 多线程消费者和生产者模型

线程消费者和生产者模型 概述:生产者和消费者模型是多线程中的经典模型。在这里我想详细的介绍下关于该模型实现的多种方式。 生产者:数据产生的源头。 消费者:数据流向的结点。 对于该模型,感觉好熟悉。如RPC框架Dubbo就是有生产者和消费者之说,也就是服务提供者和服务消费者接口。对于消息队列也是如此。但是比如Dubbo来说,服务消费者接口是通过注册中心去调用服务的生产者的。而不是直接根据地址调用。...

大佛拈花的博客 330

DCDC BUCK开关电源PCB设计

在开关电源中,BUCK(降压)电路、BOOST(升压)电路以及BUCK - BOOST(升降压)三种电路是最基本的拓扑结构。转换器又分DCDC(直流转直流)和ACDC(交流转直流),DCDC装换器结构无疑是比ACDC转换器结构简单,所以从DCDC转换器结构入手学习开关电源是一种很好的选择。本文主要从应用角度,进行相关器件的选型计算以及PCB绘制讲解DCDC 12V转5Vbuck电路。

2301_78342510的博客 6888

深入解析音频信号处理的核心算法——傅里叶变换、语音增强、回声消除与主动降噪

本文系统介绍了现代音频信号处理的核心技术。首先阐述傅里叶变换作为理论基础的重要性,它能将声音分解为频域成分。随后重点分析三大关键技术:语音增强利用谱减法、维纳滤波和深度学习从噪声中提取人声;回声消除采用自适应滤波器消除通话中的回声;主动降噪通过声波干涉原理抵消环境噪声。文章最后指出,这些技术在实际应用中协同工作,形成完整的音频处理链路,共同提升语音质量和听觉体验。随着算法进步和算力提升,音频处理技术正向着更智能、更高效的方向发展。

程序猿老樊的博客 1328

浅谈java多线程(四)——生产者消费者模型

在java多线程共享数据中有一个经典的模型就是生产者消费者模型,他是实现数据的一一对应的,就是你生产者生产一个东西,消费者就消费那个东西,并且有先后顺序只有先生产了,才能被消费。 在这我要先介绍一个方法wait():  wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入...

qq_42512179的博客 299

PostgreSQL隐式类型转换全解析:告别operator does not exist

强类型数据库是现代数据系统的基石,它在带来严谨性的同时,也常常让开发者在类型不匹配报错前束手无策。当一条SQL因bigint与text比较而抛出operator does not exist时,根源往往在于对数据库隐式转换规则的误解。PostgreSQL通过pg_cast系统表将转换划分为隐式、赋值与显式三个级别,并依据操作符解析逻辑决定是否自动提升类型。理解这些机制,不仅能快速定位JOIN、UNION、函数调用等场景下的类型错误,还能帮助开发者合理使用EXPLAIN VERBOSE、pg_typeof等工

weixin_29587015的博客 305

编写一个生产者,消费者多线程程序,一个线程随机产生数据,另一个线程显示所产生的数据.

import java.util.*;public class ThreadSample{  private boolean stop_produce = false;  private boolean stop_consume = false;  private Vector data;  private Thread producer;  private Thread consumer; 

王道JAVA 3198

Nsight Compute内存图表实战:如何快速定位CUDA内核的内存瓶颈(附配置截图)

本文详细介绍了如何使用Nsight Compute的Memory Chart功能快速定位和诊断CUDA内核中的内存性能瓶颈。通过解析内存图表中的逻辑与物理单元节点、连线颜色含义,并结合实战案例(如低L1缓存命中率、共享内存Bank冲突、全局内存访问未合并),指导开发者从可视化数据回溯至源代码,进行精准有效的内存访问优化,从而提升GPU程序性能。

zeta9的博客 481

基于Python的二手奢侈品电商平台商品保值率数据爬取与分析

本文旨在探讨如何利用Python网络爬虫技术获取二手奢侈品电商平台商品数据,并通过数据分析研究奢侈品的保值率特性。研究将使用最新的爬虫技术(包括Playwright、异步处理和数据清洗技术)来高效获取数据,并利用Pandas、Matplotlib等数据分析库进行深入的数据可视化分析。本文详细介绍了爬虫的设计思路、实现过程以及数据分析方法,为奢侈品投资和消费提供数据参考。关键词:Python爬虫、奢侈品保值率、数据分析、Playwright、异步处理。

2201_76125261的博客 512

线程同步-生产者消费者问题

在进行多线程编程时,难免还要碰到两个问题,那就线程间的互斥与同步: 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。 线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放

big_bit的博客 1万+

Puchem化合物数据批量抓取采集_宝典_教程_Python爬虫

本文共计6500字,导出到PDF达42页(含代码)。从0教你如何抓取Pubchem化合物数据。 1、 Pubchem介绍 ​ Pubchem是美国国立卫生研究院(NIH)的开放式化学数据库,自2004年推出以来,pubchem已成为科学家、学生和公众的重要化学信息资源。其专门针对化学结构搜索,是网络药理学研究经常用到的数据库之一,不仅使用方便而且免费。 ​ PubChem主要包含小分子,但也包含较大的分子,例如核苷酸,碳水化合物,脂质,肽和化学修饰的大分子。收集有关化学结构,标识符,化学和物理性..

qq_34843422的博客 6075

多线程之生产者与消费者问题

生产者消费者问题(Producer-consumer problem):生产者不断地生产产品,消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中,消费者从这个地方去除数据。 涉及的问题:要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。 主要涉及:多线程的同步问题。 1、假设生产者线程刚向数据存储空间添加了产品的名称,还没有添加产品的内容,程序就切到了消费者的线程,消费这的 线程将吧产品的名称和上

Andyの笔记 2159

【二】MADDPG多智能体算法实现(parl)【追逐游戏复现】

论文全称:Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments 论文原文:https://download.youkuaiyun.com/download/sinat_39620217/16203960 论文翻译:https://blog.youkuaiyun.com/qiusuoxiaozi/article/details/79066612 ...

丨汀、的博客 2万+

Android软键盘系统深度解析:架构、原理与实现

Android软键盘系统深度解析:架构与实现原理 本文系统剖析了Android软键盘的核心工作机制。作为系统级输入服务,软键盘具有双重属性:既是可安装的独立应用,又深度集成于系统框架中。文章详细解读了软键盘的系统架构,包括其与InputMethodManagerService(IMMS)和WindowManagerService(WMS)的交互机制,以及通过InputConnection实现的跨进程通信流程。同时分析了输入法窗口的特殊管理策略、布局调整模式,并深入探讨了输入预测引擎的实现原理,包括词典加载、

保持专注,保持热爱 116

多线程之消费者生产者问题

消费者生产者问题: 这个问题是一个多线程同步问题的经典案例,生产者负责生产对象,消费者负责将生成者产生的对象取出,两者不断重复此过程。这过程需要注意几个问题: 不论生产者和消费者有几个,必须保证: 1.生产者每次产出的对象必须不一样,产生的对象有且仅有出现一次; 2.消费者每次取出的对象必须不一样,取出的对象有且仅有出现一次; 3.一定是先产生该对象,然后对象才能被取出,顺序不能乱; ...

zjt980452483的博客 4554

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

多线程的生产者和消费者问题

多线程的生产者和消费者问题是比较经典的多线程问题,如果知道编码解决生产者和消费者问题,那么对于多线程应该基本算掌握了。我不知道大家的生产者和消费者问题是怎么样的(应该有几个版本吧),这里我说下我的生产者和消费者问题: 有多个生产线程,他们只负责生产资源;有多个消费者,同样他们只负责消费。但是他们需要满足下面条件: 生产者:只有当资源没有的时候,生产者才开始生产,但是为了防止浪费,每次只能生产指定数量的资源。当生产者生产完足够资源时,就进入睡眠,同时叫醒消费者去消费;

YuZhiHui_No1的专栏 3390

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

用线程实现经典生产者消费者问题

2)用线程实现经典生产者消费者问题 解决生产者消费者问题的方法一般采用同步机制保证生产者和消费者之间的同步,这种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。 同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。Java语言在多线程编程上实现了完全对象化,提供了对同步机制的良好支持。 生产者与消费者模型中,要保证以下几点: 同一时间内只能有一个生产者生产 生产方法加锁sychronized 同一时间

qq_44719229的博客 653

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

多线程解决生产者与消费者问题

生产者消费者问题是一个很有名的线程同步问题,以前学操作系统时,没怎么搞懂,直到现在学java学到多线程这一块才搞懂。该问题描述的是两个共享固定大小的缓冲区的线程问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据.        要解决该问题,就必须让

邓威的博客 3107

线程-生产者消费者问题

此文章的目的在于利用线程的互斥,解决生产者消费者问题。其中使用了关键字sychronized。线程的内容可以一样,但是对应不同的内存地址。运行起来相互独立,是两个完全独立的进程。producer.java文件:package ProducerConsumer;class Producer extends Thread{  CircularBuffer cbp=null;   Producer(Ci

congliu的专栏 1046

java多线程之生产者消费者经典问题

今天研究了一下java多线程,顺便写了一下多线程中的经典问题-----生产者消费者经典问题,参照了网上的各种写法之后自己写了一个,如下所示 /**生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二,既然是生产者、消费者,那么生产者类和消费者类就是必须的 * 第三,生产什么,消费什么,所以物品类是必须的,这里是馒头类 * 第四,既然是线程,那么就不是一对

亡羊补牢 5万+

用线程解决生产者消费者问题

问题描述:            生产者和消费者问题,我想大家肯定都很熟悉。就是有生产者在生产,生产出的产品(我们在这里用窝头来作比喻)放到一个篮子里,然后有消费者拿篮子里的窝头来吃。            问题分析:             1、条件分析,如果生产者生产了窝头,就应该叫消费者来吃;如果自己生产的窝头把篮子都装满了,就要先停下来,然后通知消费者去吃窝头;同理,消费者吃了窝头,

黎明前的黑暗 2987

多线程的生产者-消费者问题实现

这个实现使用了信号量和互斥锁来保证线程安全,避免竞态条件。生产者会持续向缓冲区添加项目,而消费者会持续从缓冲区取出项目,直到loops变量减到0。这是一个多线程的生产者-消费者问题实现。

XLYcmy的博客 1663

Java多线程实现生产者消费者问题

Java多线程实现生产者消费者问题 问题描述: 假设在汉堡店中,有最多能放10个汉堡的窗口,有生产汉堡的厨师,还有前来消费汉堡的消费者。厨师在窗口没摆满汉堡时一直生产汉堡放到窗口,消费者在窗口有汉堡时能进行消费。 模型抽象: 生产者(厨师):新加产品到缓冲池,当缓冲池产品达到最大值(满了)时进入wait状态。 消费者:提取缓冲池中的产品,当缓冲池产品为空时进入wait状态等待 缓冲池(窗口):存放...

qq_41257358的博客 1700

Linux 系统应用编程——多线程经典问题(生产者-消费者)

“生产者——消费者”问题是Linux多线程编程中的经典问题,主要是利用信号量处理线程间的同步和互斥问题。          “生产者——消费者”问题描述如下:           有一个有限缓冲区(这里用有名管道实现 FIFO 式缓冲区)和两个线程:生产者和消费者,它们分别不停地把产品放入缓冲区中拿走产品。一个生产者在缓冲区满的时候必须等待,一个消费者在缓冲区空的时候也不IXUS等待。另外,因

知秋一叶 1万+
上一篇: 快速排序
下一篇: Java IO学习笔记:概念与原理
三易的博客
博客等级 码龄15年 42粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值