Java与Go:并发

在此之前,我们先要明白什么是并发?为什么要并发编程?

在计算机中,同一时刻,只能有一条指令,在一个CPU上执行 后面的指令必须等到前面指令执行完才能执行,就是串行。在早年CPU核心数还少的时候倒是没什么。但是现如今,CPU性能(核心数和频率)已经不同往昔,为了充分利用CPU性能,我们引入并发。就好比银行只有5个窗口,有5个人要办事,就可以一起处理,第六个人到来才需要排队。

Java如何进行并发编程

在 Java 中进行并发编程可以利用语言和库提供的特性,如线程、线程池、同步机制等。Java 为并发编程提供了许多有用的工具和库,包括基本的 Thread 类、并发集合、锁、条件变量等。在 Java 7 及以上版本中,java.util.concurrent 包还提供了更高层次的并发编程工具,包括线程池、并发队列、异步任务(FutureCompletableFuture)等。

1. 开辟新线程

  • Thread:Java 提供了 Thread 类来创建和管理线程。你可以通过继承 Thread 类或实现 Runnable 接口来定义线程。
public class MyThread extends Thread {@Overridepublic void run() {// 在这个方法中定义线程要执行的任务System.out.println("Thread is running");}public static void main(String[] args) {// 创建 MyThread 类的实例MyThread myThread = new MyThread();// 启动线程myThread.start();}
}
  • Runnable 接口:通过实现 Runnable 接口,并将其传递给 Thread 类的构造函数,来定义线程的执行逻辑。
public class MyRunnable implements Runnable {@Overridepublic void run() {// 在这个方法中定义线程要执行的任务System.out.println("Runnable is running");}public static void main(String[] args) {// 创建 MyRunnable 类的实例MyRunnable myRunnable = new MyRunnable();// 将 Runnable 对象传递给 Thread 构造函数Thread thread = new Thread(myRunnable);// 启动线程thread.start();}
}

2. 同步与锁

  • synchronized 关键字:用于在方法或代码块上加锁,确保在同一时间只有一个线程可以执行受保护的代码。
  • Lock 接口:提供了 synchronized 的替代方法,更灵活的锁定机制。
  • ReadWriteLock:提供了读写锁,用于优化读多写少的场景。

3. 线程池

  • ExecutorService:用于管理线程池,可以通过 Executors 类提供的方法来创建不同类型的线程池。
  • ScheduledExecutorService:用于安排定时或周期性的任务执行。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class ConcurrencyDemo {public static void main(String[] args) {// 创建一个固定大小的线程池ExecutorService executor = Executors.newFixedThreadPool(3);// 提交任务给线程池Future<?> future1 = executor.submit(() -> {System.out.println("任务 1 开始");// 执行任务逻辑System.out.println("任务 1 结束");});Future<?> future2 = executor.submit(() -> {System.out.println("任务 2 开始");// 执行任务逻辑System.out.println("任务 2 结束");});// 等待任务执行完成try {future1.get(); // 阻塞直到任务 1 完成future2.get(); // 阻塞直到任务 2 完成} catch (Exception e) {e.printStackTrace();}// 关闭线程池executor.shutdown();}
}

创建了一个固定大小为 3 的线程池,然后提交了两个任务,并等待它们执行完毕。最后关闭线程池。

4. 并发集合

  • java.util.concurrent 包中的并发集合:例如 ConcurrentHashMapCopyOnWriteArrayListConcurrentLinkedQueue 等,适合在多线程环境下使用。

5. 异步任务与回调

  • Future 接口:代表异步计算的结果。可以通过 ExecutorService 提供的方法提交任务,得到 Future 对象。
  • CompletableFuture:更高级的异步任务工具,提供链式回调、组合和异常处理等功能。

6. 其他并发工具

  • CountDownLatch:用于线程同步,让线程等待直到某些操作完成。
  • CyclicBarrier:一个同步点,允许多个线程等待彼此到达一个状态。
  • Semaphore:用于控制资源的访问数量。

Go语言怎么并发

Go 语言以其强大的并发编程特性而闻名。Go 语言提供了一些基本概念和机制来处理并发,包括 goroutines、channels 和 select 语句。这些工具使得 Go 在处理并发任务时非常高效且易于编写。

1. Goroutine

  • Goroutine 是 Go 语言中的轻量级线程。通过使用 go 关键字,可以在后台启动一个新的 goroutine 来执行任务。
  • Goroutine 是非常轻量级的,可以同时启动大量 goroutine,而不会对系统资源产生很大的负担。
package mainimport ("fmt"
)func sayHello() {fmt.Println("Hello!")
}func main() {go sayHello() // 启动一个新的 goroutine 执行 sayHello 函数fmt.Println("Main goroutine")
}

2. Channels

  • Channels 是 Go 语言中用于 goroutine 之间通信的工具。通过 channels,可以在不同的 goroutine 之间传递数据。
  • 可以使用 make 函数创建 channels,并通过 <- 运算符发送和接收数据。
package mainimport ("fmt"
)func producer(ch chan int) {for i := 0; i < 5; i++ {ch <- i // 发送数据到 channelfmt.Printf("Produced: %d\n", i)}close(ch) // 关闭 channel
}func consumer(ch chan int) {for value := range ch { // 从 channel 接收数据fmt.Printf("Consumed: %d\n", value)}
}func main() {ch := make(chan int) // 创建一个整型 channelgo producer(ch) // 启动生产者 goroutinego consumer(ch) // 启动消费者 goroutine// 让主程序等待 goroutine 结束// 可以使用 time.Sleep() 或 wait group 来实现
}

3. Select 语句

  • select 语句用于在多个 channel 上等待,并选择其中一个准备好的 channel 进行通信。
  • select 语句类似于 switch 语句,但它是针对 channels 的。
package mainimport ("fmt""time"
)func main() {ch1 := make(chan int)ch2 := make(chan int)go func() {time.Sleep(2 * time.Second)ch1 <- 1}()go func() {time.Sleep(1 * time.Second)ch2 <- 2}()select {case value := <-ch1:fmt.Printf("Received %d from ch1\n", value)case value := <-ch2:fmt.Printf("Received %d from ch2\n", value)}
}

select 语句等待两个 channel 之一发送数据,然后接收数据并执行相应的分支。

这些是 Go 语言中并发编程的基本概念和用法。通过组合这些特性,Go 语言可以处理复杂的并发任务。

Java的虚拟线程

Java 21 中引入了 虚拟线程(Virtual Threads) ,它是一种新的线程实现,旨在提高并发应用程序的性能和可扩展性。虚拟线程与传统线程不同,它们是一种轻量级的线程实现,可以在 Java 虚拟机(JVM)上更有效地处理大量并发任务。

以下是虚拟线程的主要特点和优势:

1. 轻量级

  • 虚拟线程是轻量级的,创建和销毁的开销很小,因此可以在应用程序中创建大量虚拟线程。
  • 与传统线程相比,虚拟线程的资源占用较小,这使得在大量并发任务的场景下更加高效。

2. 阻塞友好

  • 虚拟线程可以友好地阻塞在 I/O 操作或其他同步操作上,而不会影响其他虚拟线程的执行。
  • JVM 可以将阻塞的虚拟线程切换到其他可运行的虚拟线程,保持高效的并发执行。

3. 无缝集成

  • 虚拟线程与现有的 Java 代码无缝集成,这意味着开发者可以在现有的代码基础上直接使用虚拟线程。
  • 开发者可以继续使用现有的并发 API,如 ThreadExecutorService 等,只需将其替换为虚拟线程的实现即可。

4. 简单的编程模型

  • 虚拟线程提供了一个更简单的编程模型,因为开发者可以像使用普通线程一样使用虚拟线程。
  • 开发者可以更专注于业务逻辑,而不必担心底层线程管理的复杂性。

5. 高性能

  • 虚拟线程的调度和执行更高效,可以充分利用多核 CPU 的优势。
  • 对于需要处理大量并发任务的应用程序,虚拟线程可以显著提高性能。

使用示例:

使用虚拟线程非常简单,只需在 Thread 类的实例化中指定 Thread.ofVirtual() 作为工厂方法即可:

public class VirtualThreadExample {public static void main(String[] args) {Runnable task = () -> {System.out.println("Virtual thread is running");};// 创建一个虚拟线程Thread virtualThread = Thread.ofVirtual().start(task);// 等待虚拟线程执行完毕try {virtualThread.join();} catch (InterruptedException e) {e.printStackTrace();}}
}

我们使用 Thread.ofVirtual() 创建了一个虚拟线程,并启动它来执行指定的任务。与传统线程的使用类似,但虚拟线程在性能和资源效率方面有更大的优势。

虚拟线程是 Java 21 的一个重要特性,为开发者提供了处理大量并发任务的强大工具。

往期推荐

Java与Go:字符串转IP地址

Java与Go:文件IO

Java vs. Go:时间函数

Java与Go:字符串方法

Java与Go:方法和接口

Java与Go:引用和指针

Java与Go:对象

Java与Go:Map

Java 与 Go:可变数组

Java 与 Go:数组

在这里插入图片描述

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

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

相关文章

Android版本依赖Version catalog

曾经我们使用config.gradle文件进行版本依赖配置&#xff0c;然后在project的build.gradle.kts中使用如下方式引入&#xff1a; apply(from "./config.gradle") 缺点&#xff1a;在project的module中引用无任何提示&#xff0c;无法跳转到指定引用 一、创建versio…

临床+康复的一体化治疗服务,把握黄金康复时间

随着我院脑血管病人&#xff0c;重症病人及骨科病人康复需求的日渐增多&#xff0c;为了使每位住院患者在治疗原发病的同时&#xff0c;第一时间接受到康复治疗&#xff0c;提高病人的生活质量&#xff0c;降低致残率&#xff0c;我院康复治疗科在院领导的大力支持下&#xff0…

C语言之递归函数、例题详解以及注意事项

目录 前言 一、递归的概念 二、递归例题详解 例1&#xff1a;斐波那契数列 例2&#xff1a;求次方 例3&#xff1a;求各位数之和 例4&#xff1a;阶乘 例5&#xff1a;顺序打印 三、递归的注意事项 总结 前言 本文将和大家分享一些递归函数的相关知识&#xff0c;技巧…

EPAI手绘建模APP颜色、贴图、材质、样式

⑦ 颜色选择页面 1) 颜色环选色。 图 65 颜色选择器-颜色环 2) RGB选色。 图 66 颜色选择器-RGB 3) HSL选色。 图 67 颜色选择器-HSL 4) 国风颜色库选色。 图 68 颜色选择器-国风 5) CSS颜色库选色。 图 69 颜色选择器-CSS 6) 历史颜色&#xff1a;保存最近使用的多个颜色&…

vue快速入门(五十三)使用js进行路由跳转

注释很详细&#xff0c;直接上代码 上一篇 新增内容 几种常用的路由跳转方式演示 源码 App.vue <template><div id"app"><div class"nav"><!-- router-link 自带两个高亮样式类 router-link-exact-active和router-link-active区别&a…

3.SpringSecurity基本原理

SpringSecurity本质是一个过滤器链。十多个过滤器构成一个过滤器链。 这些过滤器在项目启动就会进行加载。每个过滤器执行放行操作才会执行下一个过滤器。 常见过滤器 FilterSecurityInterceptor 是一个方法级的权限过滤器&#xff0c;基本位于过滤器链的最底部。 Excepti…

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

HTML_CSS学习:CSS盒子模型

一、CSS中常用的长度单位 相关代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>CSS中常用的长度单位</title><style>html{font-size: 40px;}#d1{/*第一种长度单位&…

开源模型应用落地-LangChain高阶-Tools工具-集成agents(四)

一、前言 LangChain 的 tools 是一系列关键组件&#xff0c;它们提供了与外部世界进行交互的能力。通过适当的使用这些组件&#xff0c;可以简单实现如执行网络搜索以获取最新信息、调用特定的 API 来获取数据或执行特定的操作、与数据库进行交互以获取存储的信息等需求。 本章…

安装vscode基础配置,es6基础语法,

https://code.visualstudio.com/ es6 定义变量 const声明常量&#xff08;只读变量&#xff09; // 1、声明之后不允许改变 const PI “3.1415926” PI 3 // TypeError: Assignment to constant variable. // 2、一但声明必须初始化&#xff0c;否则会报错 const MY_AGE /…

01-MySQL 基础篇笔记

一、MySQL 概述 1.1 数据库相关概念 数据库&#xff1a;&#xff08;DB&#xff1a;DataBase&#xff09; 存储数据的仓库&#xff0c;数据是有组织的进行存储 数据库管理系统&#xff1a;&#xff08;DBMS&#xff1a;DataBase Management System&#xff09; 操作和管理数…

java spring 09 Bean的销毁过程

1.Bean销毁是发送在Spring容器关闭过程中的 AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) context.getBean("userService");userService.test();// 容器关闭cont…

手撕spring框架(5)

手撕spring框架(5) 相关系列 手撕spring框架&#xff08;1&#xff09; 手撕spring框架&#xff08;2&#xff09; 手撕spring框架&#xff08;3&#xff09; 手撕spring框架&#xff08;4&#xff09; 这是本专题最后一节了&#xff0c;主要是讲述自定义一个注解&#xff0c;实…

14_Scala面向对象编程_属性

属性 1.类中属性声明 // 1.给Scala声明属性&#xff1b;var name :String "zhangsan"val age :Int 302.系统默认赋值 scala由于初始化变量必须赋值&#xff0c;为了解决此问题可以采用下划线赋值&#xff0c;表示系统默认赋值 , –但是此方法局限于变量&…

太阳能光伏光热综合利用(PVT)

PVT系统介绍 传统太阳能系统是太阳光直接加热水&#xff0c;效率高&#xff0c;但是需要有防冻措施&#xff0c;且在太阳光不充足时需要增加电辅热&#xff0c;受天气影响大&#xff0c;且电加热能耗高。传统发电是将直流电转化为交流电&#xff0c;再提供给用户使用。此PVT技…

特斯拉全自动驾驶系统Tesla‘s Full-Self Driving (FSD)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Overview Tesla’s FSD is a suite of features that includes Autopilot, Navigate on Autopilot, Auto Lane Change, Autopark, Summon, and Traffic Light and Stop Sig…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-12-蜂鸣器

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

力扣每日一题104:二叉树的最大深度

题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,2…

C#中.net8WebApi加密解密

尤其在公网之中&#xff0c;数据的安全及其的重要&#xff0c;除过我们使用jwt之外&#xff0c;还可以对传送的数据进行加密&#xff0c;就算别人使用抓包工具&#xff0c;抓到数据&#xff0c;一时半会儿也解密不了数据&#xff0c;当然&#xff0c;加密也影响了效率&#xff…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-11.1,11.2-BSP文件目录组织

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…