当前位置:网站首页>并发编程之生产者和消费者问题
并发编程之生产者和消费者问题
2022-08-04 08:57:00 【51CTO】
简单的线程通信,一个线程对数字进行增加操作、另一个线程对线程进行减少操作。
简单解释:线程A对数字进行减少操作,但不会一直让这个数字减少下去。当减少到设定的条件,让其等待,通知其他线程获得该资源。
package com.ProductAndCustomer;
/**
* 线程之间的通信,生产者和消费者问题
*/
public class Product {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
}
}
//等待,业务,通知
class Data{
//资源类
private int num = 0;
//增加操作
public synchronized void increment() throws InterruptedException {
if(num != 0){
//等待
this.wait();
}
num ++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
//通知其他线程,+1结束
this.notifyAll();
}
//减少操作
public synchronized void decrement() throws InterruptedException {
if(num == 0){
//等待
this.wait();
}
num --;
System.out.println(Thread.currentThread().getName()+"=>"+num);
//通知其他线程,-1结束
this.notifyAll();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
测试
在多几个线程
package com.ProductAndCustomer;
/**
* 线程之间的通信,生产者和消费者问题
*/
public class Product {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
//等待,业务,通知
class Data{
//资源类
private int num = 0;
//增加操作
public synchronized void increment() throws InterruptedException {
if(num != 0){
//等待
this.wait();
}
num ++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
//通知其他线程,+1结束
this.notifyAll();
}
//减少操作
public synchronized void decrement() throws InterruptedException {
if(num == 0){
//等待
this.wait();
}
num --;
System.out.println(Thread.currentThread().getName()+"=>"+num);
//通知其他线程,-1结束
this.notifyAll();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
测试结果
这里会出现虚假唤醒
查看开发文档可知、需要修改判断语句 if修改为while
修改后的代码
package com.ProductAndCustomer;
/**
* 线程之间的通信,生产者和消费者问题
*/
public class Product {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
//等待,业务,通知
class Data{
//资源类
private int num = 0;
//增加操作
public synchronized void increment() throws InterruptedException {
while(num != 0){
//等待
this.wait();
}
num ++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
//通知其他线程,+1结束
this.notifyAll();
}
//减少操作
public synchronized void decrement() throws InterruptedException {
while(num == 0){
//等待
this.wait();
}
num --;
System.out.println(Thread.currentThread().getName()+"=>"+num);
//通知其他线程,-1结束
this.notifyAll();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
测试结果
边栏推荐
猜你喜欢
spark算子讲解
思想茶叶蛋 (Jul 31,2022)| 元宇宙(Metaverse)下了一枚什么样的蛋
2022年化工自动化控制仪表考试模拟100题及模拟考试
YOLOv5应用轻量级通用上采样算子CARAFE
[Computer recording screen] How to use bandicam to record the game setting graphic tutorial
今日睡眠质量记录71分
第一次用postgreSQL,想装主从,用的12.7 tar.gz版本。安装好后没在 share目录下找到样例配置recovery.conf.sample,是安装方式不对,还是路径不对?
【高并发基石】多线程、守护线程、线程安全、线程同步、互斥锁
ShuffleNet v2 network structure reproduction (Pytorch version)
智能健身动作识别:PP-TinyPose打造AI虚拟健身教练!
随机推荐
Quick tips for getting out of a single
Cross-species regulatory sequence activity prediction
关于#sql#的问题:后面换了一个数据库里面的数据就不能跑了
TCP的四次挥手
经典递归回溯问题之——解数独(LeetCode 37)
Interpretation of new features | MySQL 8.0 online adjustment REDO
csdn图片去水印 | 其他方法无效时的解决方案
如何快速将Zabbix5.0升级至6.0?
经典二分法查找的进阶题目——LeetCode33 搜索旋转排序数组
【论文笔记】Understanding Long Programming Languages with Structure-Aware Sparse Attention
.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)
ShuffleNet v2网络结构复现(Pytorch版)
【Attention】Dual Attention(DANet) & Fully Attention(FLA)
How to write patents are more likely to pass?
【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
C Language Lectures from Scratch Part 6: Structure
如何设计一个注册中心
华为设备配置VRRP与路由联动监视上行链路
Thread类的基本使用。
从零开始的tensorflow小白使用指北