Java转C之并发和多线程
提纲:
- 概念介绍与对比概述
- 简述Java与C在并发和多线程方面的核心区别
- 解释C11标准、POSIX、C11
<threads.h>
、Pthread等名词
- Java多线程与并发回顾
- 线程、Runnable、ExecutorService概念说明
- 同步关键字与工具类含义
- C并发基础
- 没有Java式的内置线程类,需要外部库或标准扩展
- C11标准和
<threads.h>
介绍 - POSIX Pthreads介绍
- 同步机制(互斥锁、条件变量)简单解释
- 场景与示例对比
- Java线程池与C中的手动实现线程池
- 全面示例从简单到复杂
- 最佳实践总结
概念介绍与对比概述
并发与多线程是指让程序同时(或者看起来同时)做多件事的能力。在Java中,这很容易实现:你可以创建线程对象并启动,使用内置的类和方法让多个任务并行执行。而在C中,你需要了解一些额外的概念和库,因为C语言本身最初并没有把多线程放入标准中。
C11 标准是什么?
C语言有不同的标准版本,由国际标准化组织制定。C11(读作"See eleven")是2011年发布的C语言标准版本。在C11中,首次引入了一些基本的多线程支持的头文件 <threads.h>
,提供了创建和管理线程的基础功能,但功能比较有限,远不如Java丰富。
POSIX 是什么?
POSIX(Portable Operating System Interface)是一个操作系统接口标准,定义了一套在不同系统上通用的API和特性。其中包括线程(称为Pthreads,也就是POSIX Threads)相关的API。POSIX是个标准,Unix、Linux和macOS等系统遵循POSIX标准,可使用相同的线程函数。
简单来说:
- POSIX是一个标准,规定了一些函数和行为,让程序在多个系统上都能以相似方式运行。
- Pthreads是POSIX标准中定义的一组用于多线程的API函数。
<threads.h>
是什么?
<threads.h>
是C11标准引入的头文件,提供了创建、加入(thread join)线程的函数,还有互斥锁等基本同步机制。它是C标准的一部分,但实现程度在不同编译器和系统上可能不完全一致。此外,它比POSIX线程API更简单和功能较少。
pthread(Pthreads)是什么?
Pthread是POSIX Threads的简称,是在POSIX标准中定义的一套多线程API。不属于C标准本身,是操作系统提供的库,但在类Unix系统(Linux/macOS)上很常用。相比C11 <threads.h>
,Pthreads功能更强大、使用更广泛。
Java多线程与并发回顾
在Java中,多线程功能是内置的:
- 使用
Thread
类或Runnable
接口创建线程。 - 使用
synchronized
关键字保证线程安全访问共享数据。 volatile
关键字保证变量对所有线程可见。- 高级框架:
ExecutorService
、ForkJoinPool
、CompletableFuture
、ConcurrentHashMap
等工具类,使并发编程更简单。
Java简单示例:
class MyTask implements Runnable {public void run() {System.out.println("Running in " + Thread.currentThread().getName());}
}public class Main {public static void main(String[] args) {Thread t = new Thread(new MyTask());t.start(); // 启动线程}
}
这里Java很容易就创建并运行一个新线程。
C并发基础
C最初设计时没有多线程概念。多线程特性是后来才通过标准扩展和第三方库加入的。
C11 <threads.h>
简单说明
C11标准给C语言增加了一个基础的多线程支持头文件 <threads.h>
,其中有:
thrd_create()
创建线程thrd_join()
等待线程结束- 互斥锁
mtx_t
用于保护共享数据 - 原子操作和简单的同步工具
然而,这套API功能有限,不如Java丰富,也不如POSIX pthreads常用。
POSIX Pthreads
在Unix/Linux/macOS系统上,常用POSIX线程库(pthreads)来实现多线程,包括:
pthread_create()
创建线程pthread_join()
等待线程结束pthread_mutex_t
互斥锁、pthread_cond_t
条件变量实现复杂同步
Pthreads是非常常见的C多线程方式,相对于C11 <threads.h>
来说功能更丰富。在Windows平台有自己的多线程API(Win32 Threads)。
同步机制介绍
在多线程中,如果多个线程同时访问和修改共享变量,可能会出错,需要同步。
- 互斥锁(mutex):一次只允许一个线程进入某个代码区,类似Java中的
synchronized
锁。 - 条件变量(condition variable):让线程等待特定条件(如队列不空),当条件满足时通知等待线程继续执行。
Java中有高级数据结构和锁,而C中则需手动使用pthread_mutex_lock()
和pthread_mutex_unlock()
来锁定和解锁资源。
场景与示例对比
Java线程池场景
在Java中,你可能有10个任务要处理,这些任务可以并行执行。你只需使用ExecutorService
创建一个固定大小的线程池,然后submit()
任务:
import java.util.concurrent.*;public class JavaThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(4); // 创建4线程的池for (int i = 0; i < 10; i++) {final int taskId = i;executor.submit(() -> {System.out.println("Java Task " + taskId + " by " + Thread.currentThread().getName());});}executor.shutdown();}
}
这样Java自动管理线程、队列和任务调度,不需要你手动处理同步队列等细节。
C中实现类似线程池
C中没有内置线程池,需要手动:
- 使用Pthreads创建多个工作线程
- 使用队列存放任务,队列需要锁和条件变量
- 线程等待队列有任务后获取并执行
示例思路(简化):
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>#define MAX_TASKS 100
typedef struct {void (*func)(void*);void *arg;
} Task;Task tasks[MAX_TASKS];
int task_count = 0;
int stop = 0;pthread_mutex_t task_lock;
pthread_cond_t task_cond;void add_task(void (*func)(void*), void *arg) {pthread_mutex_lock(&task_lock);if (task_count < MAX_TASKS) {tasks[task_count].func = func;tasks[task_count].arg = arg;task_count++;pthread_cond_signal(&task_cond);}pthread_mutex_unlock(&task_lock);
}void* worker(void* arg) {while (1) {pthread_mutex_lock(&task_lock);while (task_count == 0 && !stop) {pthread_cond_wait(&task_cond, &task_lock);}if (stop && task_count == 0) {pthread_mutex_unlock(&task_lock);break;}Task task = tasks[--task_count];pthread_mutex_unlock(&task_lock);// 执行任务task.func(task.arg);}return NULL;
}void print_msg(void *arg) {char* msg = (char*)arg;printf("C Thread %ld: %s\n", pthread_self(), msg);free(msg);
}int main() {pthread_mutex_init(&task_lock, NULL);pthread_cond_init(&task_cond, NULL);pthread_t threads[4];for (int i = 0; i < 4; i++) {pthread_create(&threads[i], NULL, worker, NULL);}for (int i = 0; i < 10; i++) {char *msg = (char*)malloc(50);sprintf(msg, "Task %d", i);add_task(print_msg, msg);}sleep(1); // 等待任务执行一会儿pthread_mutex_lock(&task_lock);stop = 1;pthread_cond_broadcast(&task_cond);pthread_mutex_unlock(&task_lock);for (int i = 0; i < 4; i++) {pthread_join(threads[i], NULL);}pthread_mutex_destroy(&task_lock);pthread_cond_destroy(&task_cond);return 0;
}
这个C程序实现了一个简易的"线程池":
- 使用
pthread_create()
启动4个工作线程。 - 当添加任务时,用锁保护队列并signal条件变量。
- 工作线程被条件变量唤醒后从队列中取出任务执行。
比起Java的一行Executors.newFixedThreadPool(4)
简单声明,这在C中要写许多代码手动控制。
对比表格
特性 | Java | C |
---|---|---|
内置并发支持 | 有,Thread 、Runnable 、ExecutorService | 无强制要求的内建库,C11有基础<threads.h> 但简化版 |
线程创建 | new Thread(...) +start() 或 Executor 框架 | pthread_create() (POSIX) 或 thrd_create() (C11) |
同步方式 | synchronized 、Lock 、volatile 、高级工具类 | pthread_mutex_t 互斥锁、pthread_cond_t 条件变量 |
高级并发工具 | 丰富:ExecutorService 、并发集合、CompletableFuture | 需自行实现,没有内置高级并发容器 |
内存模型 | 明确的Java内存模型保证线程通信语义 | C标准中直到C11才有简单原子操作,无完整高级内存模型 |
学习与使用难度 | 易学易用、类库丰富、工具多 | 难度高,需手动实现许多逻辑 |
最佳实践与总结
-
对于Java:
- 优先使用
ExecutorService
、BlockingQueue
等高级API。 - 使用
synchronized
或Lock
保证线程安全访问共享数据。 - 利用Java内置内存模型和工具类减少错误。
- 优先使用
-
对于C:
- 使用POSIX线程(pthread)在类Unix系统实现多线程;在C11中可尝试
<threads.h>
但特性较弱。 - 手动使用互斥锁(
pthread_mutex_t
)和条件变量(pthread_cond_t
)实现同步。 - 无内置高级数据结构,需要自制线程安全队列、线程池。
- 更细致但更繁琐的内存和资源管理,避免内存泄漏和死锁。
- 使用POSIX线程(pthread)在类Unix系统实现多线程;在C11中可尝试
总结:
在Java中,多线程和并发通过丰富的语言和库特性简单实现;而在C中,需要更多底层知识和手动管理来达到相似的效果。C的并发编程灵活但复杂,开发者需更谨慎和投入更多努力来确保程序高效、安全和可维护。
相关文章:
Java转C之并发和多线程
提纲: 概念介绍与对比概述 简述Java与C在并发和多线程方面的核心区别解释C11标准、POSIX、C11 <threads.h>、Pthread等名词 Java多线程与并发回顾 线程、Runnable、ExecutorService概念说明同步关键字与工具类含义 C并发基础 没有Java式的内置线程类…...
针对一个系统的权限管理这样的业务场景,使用各设计模式解说
通义灵码 下面将介绍如何在Java中使用不同的设计模式来实现权限管理系统。每个设计模式都有其特定的应用场景和实现方式,我们将逐一讲解。 1. 单例模式 (Singleton Pattern) 应用场景:确保权限管理服务在整个系统中只有一个实例,避免重复创…...
Android AppCompatImageView View.Gone状态切换到View.VISIBLE重新layout,Kotlin
Android AppCompatImageView View.Gone状态切换到View.VISIBLE重新layout,Kotlin import android.content.Context import android.util.AttributeSet import android.util.Log import androidx.appcompat.widget.AppCompatImageViewclass MyImageView : AppCompatI…...

在云上轻松部署达梦数据库
达梦数据库(DM Database)是由达梦数据库有限公司开发的一款关系型数据库管理系统(RDBMS)。作为国内领先的数据库产品,达梦数据库在政府、金融、能源、电信、交通、医疗、教育等多个行业得到广泛应用,尤其在…...
什么是厄尔米特(Hermitian)矩阵?
厄米矩阵(Hermitian Matrix)定义 在数学和物理中,厄米矩阵是满足以下条件的复方阵: A A † \mathbf{A}\mathbf{A}^\dagger AA† 其中, A † \mathbf{A}^\dagger A†表示矩阵 A \mathbf{A} A的共轭转置,即…...

React - useActionState、useFormStatus与表单处理
参考文档:react18.3.1官方文档 一些概念: React 的 Canary 和 Experimental 频道是 React 团队用于发布和测试新功能的渠道。 useActionState useActionState 是一个可以根据某个表单动作的结果更新 state 的 Hook。 const [state, formAction, isPe…...
v3账号密码登录随机图片验证码
安装插件 pnpm i identify --save图形验证码组件 <template><div class"s-canvas"><!-- 图形验证码的宽和高都来自于父组件的传值,若父组件没有传值,那么就按当前子组件的默认值进行渲染 --><canvas id"s-canvas&…...

不只是请求和响应:使用Fiddler解读Cookie与状态码全指南(下)
欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! 不只是请求和响应:使用Fiddler抓包HTTP协议全指南(上)_fiddler 获取响应脚本-CSDN博客https://blog.csdn.net/Chunfeng6yugan/article/details/144005872?spm1001.2014.3001.5501 不只是请求和响…...

java+springboot+mysql游乐园管理系统
项目介绍: 使用javaspringbootmysql开发的游乐园管理系统,系统包含管理员、员工、用户角色,功能如下: 管理员:登录后台;首页数据统计;员工管理;用户管理;游乐项目管理&…...
@RequestBody,getparameter,@RequestParam,@PathVariable之间的区别和联系
RequestBody、RequestParam、PathVariable和getParameter(你提到的可能是Java Servlet API中的方法)是用于处理HTTP请求参数的不同机制。它们各自有不同的用途和适用场景,下面将详细解释它们之间的区别和联系。 1. RequestBody 用途…...

Linx下自动化之路:Redis安装包一键安装脚本实现无网极速部署并注册成服务
目录 简介 安装包下载 安装脚本 服务常用命令 简介 通过一键安装脚本实现 Redis 安装包的无网极速部署,并将其成功注册为系统服务,开机自启。 安装包下载 redis-7.0.8.tar.gzhttp://download.redis.io/releases/redis-7.0.8.tar.gz 安装脚本 修…...

VMware虚拟机搭建和镜像配置
VMware虚拟机搭建和镜像配置 下载安装VMware 开始下载 更改安装路径,需要一个大空间的盘 更改后下一步 下一步后,选择不主动升级更新 一直下一步 直到安装完毕 输入许可密钥,我下载的版本是12,输入完成点击输入ÿ…...

红日靶场vulnstark 4靶机的测试报告[细节](一)
目录 一、测试环境 1、系统环境 2、注意事项 3、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、漏洞利用Getshell ①Struts 2 s2-045漏洞 手工利用s2-45漏洞 Msf综合利用 ②Tomcat框架(CVE-2017-12615) ③phpMyAdmin(CVE-2018-12613) 构造语句写入冰蝎木…...
深入详解人工智能机器学习常见算法——线性回归算法
深入解析线性回归算法 线性回归是机器学习和统计学中最基本、最常用的预测建模技术之一。它通过线性关系描述因变量与一个或多个自变量之间的联系,帮助我们进行数据建模和预测。本篇文章将详细介绍线性回归的基础知识、算法原理、核心概念、实现方法以及其在实际问题…...
Python 开发环境搭建
Python 开发环境搭建 flyfish 版本 Ubuntu 22.04.5 LTS PyTorch 2.5.1 cuda 12.4 python 3.12.7安装 Anaconda3 依赖 sudo apt-get install libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6安装命令 …...
OpenCV相机标定与3D重建(9)相机标定函数calibrateCameraRO()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::calibrateCameraRO 是 OpenCV 中用于相机标定的函数,它允许固定某些点来进行更精确的标定。 函数原型 double cv::calibrateCa…...

flink终止提交给yarn的任务
接上文:一文说清flink从编码到部署上线 1.查看正在执行的flink 访问地址(参考):http://10.86.97.191:8099/cluster/apps 2.终止任务 yarn application -kill appID 本文为: yarn application -kill application_17…...
算法刷题Day14:BM36 判断是不是平衡二叉树
题目链接 描述 输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。 在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树 平衡二叉树(Balanced Binary Tree),具有以下性质:它是…...

【Golang】Go语言编程思想(六):Channel,第一节,介绍Channel
Channel 下面的几个例子将会展示如何定义一个 channel: func chanDemo() {var c chan int // chan int 的含义是, c 是一个 channel, 里面的内容是 int// 上面的声明语句将会创建一个 nil channel, c nil, 它的作用将在 select 当// 中体现 }创建一个非 nil 的 c…...
【Flux.jl】 卷积神经网络
Flux.jl 是包含卷积神经网络的, 但是官方API文件中没有给出一个完整的程序框架, 只是对所需神经元给了局部解释, 此外对 model-zoo 模型动物园中的案例没有及时跟着 Flux.jl 的版本更新, 也无法运行出来结果。 因此本文搭建了一个完整可训练的卷积神经网络。 Conv 卷积算子…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...