Java转C之并发和多线程

提纲:

  1. 概念介绍与对比概述
    • 简述Java与C在并发和多线程方面的核心区别
    • 解释C11标准、POSIX、C11 <threads.h>、Pthread等名词
  2. Java多线程与并发回顾
    • 线程、Runnable、ExecutorService概念说明
    • 同步关键字与工具类含义
  3. C并发基础
    • 没有Java式的内置线程类,需要外部库或标准扩展
    • C11标准和<threads.h>介绍
    • POSIX Pthreads介绍
    • 同步机制(互斥锁、条件变量)简单解释
  4. 场景与示例对比
    • Java线程池与C中的手动实现线程池
    • 全面示例从简单到复杂
  5. 最佳实践总结

概念介绍与对比概述

并发多线程是指让程序同时(或者看起来同时)做多件事的能力。在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关键字保证变量对所有线程可见。
  • 高级框架:ExecutorServiceForkJoinPoolCompletableFutureConcurrentHashMap等工具类,使并发编程更简单。

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中要写许多代码手动控制。


对比表格

特性JavaC
内置并发支持有,ThreadRunnableExecutorService无强制要求的内建库,C11有基础<threads.h>但简化版
线程创建new Thread(...)+start()Executor框架pthread_create()(POSIX) 或 thrd_create()(C11)
同步方式synchronizedLockvolatile、高级工具类pthread_mutex_t互斥锁、pthread_cond_t条件变量
高级并发工具丰富:ExecutorService、并发集合、CompletableFuture需自行实现,没有内置高级并发容器
内存模型明确的Java内存模型保证线程通信语义C标准中直到C11才有简单原子操作,无完整高级内存模型
学习与使用难度易学易用、类库丰富、工具多难度高,需手动实现许多逻辑

最佳实践与总结

  • 对于Java

    • 优先使用ExecutorServiceBlockingQueue等高级API。
    • 使用synchronizedLock保证线程安全访问共享数据。
    • 利用Java内置内存模型和工具类减少错误。
  • 对于C

    • 使用POSIX线程(pthread)在类Unix系统实现多线程;在C11中可尝试<threads.h>但特性较弱。
    • 手动使用互斥锁(pthread_mutex_t)和条件变量(pthread_cond_t)实现同步。
    • 无内置高级数据结构,需要自制线程安全队列、线程池。
    • 更细致但更繁琐的内存和资源管理,避免内存泄漏和死锁。

总结
在Java中,多线程和并发通过丰富的语言和库特性简单实现;而在C中,需要更多底层知识和手动管理来达到相似的效果。C的并发编程灵活但复杂,开发者需更谨慎和投入更多努力来确保程序高效、安全和可维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62383.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu系统本地化搭建Maxakb+Ollama

安装docker 最详细的ubuntu 安装 docker教程-腾讯云开发者社区-腾讯云 安装Ollama Ollama官网 执行命令&#xff1a; curl -fsSL https://ollama.com/install.sh | sh安装完成后下载模型 执行命令&#xff1a; ollama run llama3.3:70b安装MaxKb 执行命令&#xff1a; d…

基于JAVA的旅游网站系统设计

摘要 随着信息技术和网络技术的迅速发展&#xff0c;人们的生活质量和观念也在发生着改变&#xff0c;各地争相发展旅游业&#xff0c;传统的 旅游社已经无法满足人们的需求&#xff0c;旅游网站将突破传统在时间和地域的限制&#xff0c;成为方便、快捷、安全、可靠的旅游 方…

【Flux.jl】 卷积神经网络

Flux.jl 是包含卷积神经网络的, 但是官方API文件中没有给出一个完整的程序框架, 只是对所需神经元给了局部解释, 此外对 model-zoo 模型动物园中的案例没有及时跟着 Flux.jl 的版本更新, 也无法运行出来结果。 因此本文搭建了一个完整可训练的卷积神经网络。 Conv 卷积算子…

H5游戏出海如何获得更多增长机会?

海外H5小游戏的崛起给了国内众多中小厂商出海发展的机会&#xff0c;开发者如何在海外市场获得更多的增长机会&#xff1f;#APP出海# H5游戏如何在海外获得核心用户&#xff1f; HTML5游戏的开发与运营者们首先可以利用量多质高的HTML5游戏&#xff0c;维持海外用户粘性&…

Next.js系统性教学:深入理解和应用组件组合模式

更多有关Next.js教程&#xff0c;请查阅&#xff1a; 【目录】Next.js 独立开发系列教程-CSDN博客 目录 更多有关Next.js教程&#xff0c;请查阅&#xff1a; 1. 什么是组件组合模式&#xff1f; 1.1 组件组合模式概述 1.2 组件组合模式的优势 2. Next.js 中的组件组合模式…

国际荐酒师Peter助力第六届地博会,推动地理标志产品国际化发展

国际荐酒师Peter Lisicky助力第六届知交会暨地博会&#xff0c;推动地理标志产品国际化发展 第六届粤港澳大湾区知识产权交易博览会暨国际地理标志产品交易博览会于2024年12月9日至11日在中新广州知识城盛大举行&#xff0c;吸引了全球众多行业专家、企业代表及相关机构齐聚一…

Mybatis 延迟加载的实现原理详细解析

Mybatis 延迟加载的实现原理详细解析 &#xff08;1&#xff09;代理对象机制的深入探讨 代理对象的生成&#xff1a;Mybatis 使用代理对象来实现延迟加载是基于 Java 的代理机制。当开启延迟加载并且配置正确后&#xff0c;对于需要延迟加载的关联对象&#xff0c;Mybatis 会…

2024 亚马逊云科技re:Invent:Werner Vogels架构哲学,大道至简 六大经验助力架构优化

在2024亚马逊云科技re:Invent全球大会第四天的主题演讲中&#xff0c;亚马逊副总裁兼CTO Dr.Werner Vogels分享了 The Way of Simplexity&#xff0c;繁简之道&#xff0c;浓缩了Werner在亚马逊20年构建架构的经验。 Werner表示&#xff0c;复杂性总是会“悄无声息”地渗透进来…

Java Web 开发学习中:过滤器与 Ajax 异步请求

一、过滤器 Filter&#xff1a; 过滤器的概念与用途 在一个庞大的 Web 应用中&#xff0c;有许多资源需要受到保护或进行特定的预处理。过滤器就像是一位智能的守卫&#xff0c;站在资源的入口处&#xff0c;根据预先设定的规则&#xff0c;决定哪些请求可以顺利访问资源&…

ThinkPHP框架审计--基础

基础入门 搭建好thinkphp 查看版本方法&#xff0c;全局搜version 根据开发手册可以大致了解该框架的路由 例如访问url http://127.0.0.1:8094/index.php/index/index/index 对应代码位置 例如在代码下面添加新方法 那么访问这个方法的url就是 http://127.0.0.1:8094/index.…

浅谈Python库之‌Requests

一、‌Requests的介绍 Requests 是一个简单易用的 HTTP 库&#xff0c;用于发送各种 HTTP 请求。它由 Kenneth Reitz 创建&#xff0c;并广泛用于 Python 社区中。 二、‌Requests的特点 1、人性化的 API&#xff1a;简洁的接口使得编写请求代码变得简单直观。 2、跨平台&…

如何在vue中使用ECharts

一. 打开ECharts官网,点击快速入门 下面是ECharts官网的链接 https://echarts.apache.org/ 二.在vue中使用 1.首先先引入Echarts js文件 如下图&#xff0c;下面的第一张图片是官网的实现&#xff0c;第二章图片是我根据官网的实现 2.给ECharts 创建一个DOM容器 3. 使用ec…

网络原理之 IP 协议

目录 1. IP 协议报文格式 2. 网段划分 3. 地址管理 1) 动态分配 2) NAT 机制 (网络地址转换) 3) IPv6 4. 路由选择 1. IP 协议报文格式 IP 协议是网络层的重点协议。 网络层要做的事情&#xff0c;主要就是两方面&#xff1a; 1) 地址管理 制定一系列的规则&#xff…

HyperMesh CFD功能详解:后处理功能Part 2

Clips Clips 按钮包含两个工具。Box Clip用于空间上的裁剪&#xff0c;Scalar Clip可以根据物理量的范围裁剪。 示例&#xff1a;Box Clips 裁剪 示例&#xff1a;Scalar Clips 裁剪 通过裁剪&#xff0c;仅显示density范围是10~20的等值面 示例&#xff1a;显示效果控制 部分透…

Java项目实战II基于微信小程序的跑腿系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的现代生活中&…

【机器学习与数据挖掘实战案例01】基于支持向量回归的市财政收入分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支&#xff0c;专注于让计算机系统通过数据学习和改进。它利用统计和计算方法&#xff0c;使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数…

windows下nacos启动报错:java.lang.unsatisfiedLinkError: C:\USers\乱码AppData\xxx.dll

问题 看了许多别的帖子&#xff0c;大家都是因为缺少dll包&#xff0c;下载安装 Microsoft Visual C 2015 Redistributable 就可以。但我试过了不行。思来想去&#xff0c;之前正常的时候用的JDK版本是17&#xff0c;后面别的项目用1.8给切换回来了。然后尝试配置环境变量将JD…

JavaEE 【知识改变命运】03 多线程(3)

文章目录 多线程带来的风险-线程安全线程不安全的举例分析产出线程安全的原因&#xff1a;1.线程是抢占式的2. 多线程修改同一个变量&#xff08;程序的要求&#xff09;3. 原子性4. 内存可见性5. 指令重排序 总结线程安全问题产生的原因解决线程安全问题1. synchronized关键字…

并发在前端中的应用?

‌并发在前端中的应用主要体现在处理多个请求和优化页面加载速度方面‌。前端并发处理通常涉及在极短时间内发送多个数据请求&#xff0c;例如在页面渲染时同时请求多个数据。通过并发处理&#xff0c;可以显著减少页面加载时间&#xff0c;提升用户体验。 前端并发处理的具体…

【力扣】409.最长回文串

问题描述 思路解析 因为同时包含大小写字母&#xff0c;直接创建个ASCII表大小的桶来标记又因为是要回文子串&#xff0c;所以偶数个数的一定可以那么同时&#xff0c;对于出现奇数次数的&#xff0c;我没需要他们的次数-1&#xff0c;变为偶数&#xff0c;并且可以标记出现过…