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.pswp.cn/web/62383.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62383.shtml
英文地址,請注明出處:http://en.pswp.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;并且可以標記出現過…