Java并发系列之基础二

『死磕Java并发编程系列』并发编程工具类之CountDownLatch 《死磕 Java 并发编程》系列连载中,大家可以关注一波: ????????『死磕Java并发编程系列』 01 十张图告诉你多线程那些破事 『死磕Java并发编程系列』 02 面试官:说说什么是Java内存模型? 『死磕Java并发编程系列』 03 面试必问的CAS原理你会了吗? 『死磕Java并发编程系列』 04 面试官:说说Atomic原子类的实现原理? ????????『死磕Java并发编程系列』 05 图解Java中那18 把锁 在日常编码中,Java 并发编程可是少不了,试试下面这些并 阅读详情

这里写图片描述

1. 并发编程三要素

  • 原子性:即一个不可再被分割的颗粒。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。
  • 有序性:程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)
  • 可见性:当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值。

2. 线程的五大状态

  1. 创建状态:当用 new 操作符创建一个线程的时候
  2. 就绪状态:调用 start 方法,处于就绪状态的线程并不一定马上就会执行 run 方法,还需要等待CPU的调度
  3. 运行状态:CPU 开始调度线程,并开始执行 run 方法
  4. 阻塞状态:线程的执行过程中由于一些原因进入阻塞状态比如:调用 sleep 方法、尝试去得到一个锁等等​​
  5. 死亡状态:run 方法执行完 或者 执行过程中遇到了一个异常

3. 悲观锁与乐观锁

  • 悲观锁:每次操作都会加锁,会造成线程阻塞。
  • 乐观锁:每次操作不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止,不会造成线程阻塞。​

4. 线程之间的协作

4.1 wait/notify/notifyAll

均是Object 类的方法需要注意的是:这三个方法都必须在同步的范围内调用​

  • 1、wait:阻塞当前线程,直到 notify 或者 notifyAll 来唤醒​​​​

wait有三种方式的调用

  • wait()

必要要由 notify 或者 notifyAll 来唤醒​​​​

  • wait(long timeout)

在指定时间内,如果没有notify或notifAll方法的唤醒,也会自动唤醒。

  • wait(long timeout, long nanos)

本质上还是调用一个参数的方法

  • 2、notify:只能唤醒一个处于 wait 的线程
  • 3、notifyAll:唤醒全部处于 wait 的线程​

4.2 sleep/yield/join

Thread 类的方法

1、sleep:让当前线程暂停指定时间,只是让出CPU的使用权,并不释放锁

2、yield:暂停当前线程的执行,也就是当前CPU的使用权,让其他线程有机会执行,不能指定时间。会让当前线程从运行状态转变为就绪状态,此方法在生产环境中很少会使用到
​​​​
3、join:等待调用 join 方法的线程执行结束,才执行后面的代码其调用一定要在 start 方法之后(看源码可知)​使用场景:当父线程需要等待子线程执行结束才执行后面内容或者需要某个子线程的执行结果会用到 join 方法​

5. volatile 关键字

5.1 定义

java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。

valitate是轻量级的synchronized,不会引起线程上下文的切换和调度,执行开销更小。

5.2 原理

  1. 使用volitate修饰的变量在汇编阶段,会多出一条lock前缀指令
  2. 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成
  3. 它会强制将对缓存的修改操作立即写入主存4. 如果是写操作,它会导致其他CPU里缓存了该内存地址的数据无效

5.3 作用

内存可见性多线程操作的时候,一个线程修改了一个变量的值 ,其他线程能立即看到修改后的值防止重排序即程序的执行顺序按照代码的顺序执行(处理器为了提高代码的执行效率可能会对代码进行重排序)

并不能保证操作的原子性(比如下面这段代码的执行结果一定不是100000)

public class ValitateTest {
    public volatile int inc = 0;
    public void increase() {
       inc = inc + 1;
    }
    public static void main(String[] args) {
       final testValitate test = new testValitate();
       for (int i = 0; i < 100; i++) {
           new Thread() {
               public void run() {
                   for (int j = 0; j < 1000; j++)
                       test.increase();
               }
           }.start();
       }
       while (Thread.activeCount() > 2) {  //保证前面的线程都执行完
           Thread.yield();
       }
       System.out.println(test.inc);
    }
}

6. synchronized 关键字

确保线程互斥的访问同步代码

6.1 定义

synchronized是JVM实现的一种锁,其中锁的获取和释放分别是monitorenter和monitorexit指令,该锁在实现上分为了偏向锁、轻量级锁和重量级锁,其中偏向锁在 java1.6 是默认开启的,轻量级锁在多线程竞争的情况下会膨胀成重量级锁,有关锁的数据都保存在对象头中。

6.2 原理

加了synchronized关键字的代码段,生成的字节码文件会多出monitorenter和monitorexit两条指令(利用javap -verbose 字节码文件可看到)。

加了 synchronized 关键字的方法,生成的字节码文件中会多一个 ACC_SYNCHRONIZED 标志位,当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。 其实本质上没有区别,只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成。

6.3 关于使用

  • 修饰普通方法同步对象是实例对象
  • 修饰静态方法同步对象是类本身
  • 修饰代码块可以自己设置同步对象​

6.4 缺点

会让没有得到锁的资源进入Block状态,争夺到资源之后又转为Running状态,这个过程涉及到操作系统用户模式和内核模式的切换,代价比较高。Java1.6为 synchronized 做了优化,增加了从偏向锁到轻量级锁再到重量级锁的过度,但是在最终转变为重量级锁之后,性能仍然较低。

7. CAS

AtomicBoolean,AtomicInteger,AtomicLong以及 Lock 相关类等底层就是用 CAS实现的,在一定程度上性能比 synchronized 更高。

7.1 什么是CAS

CAS全称是Compare And Swap,即比较替换,是实现并发应用到的一种技术。操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。

7.2 为什么会有CAS

如果只是用 synchronized 来保证同步会存在以下问题 synchronized 是一种悲观锁,在使用上会造成一定的性能问题。在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。一个线程持有锁会导致其它所有需要此锁的线程挂起。

7.3 实现原理

Java不能直接的访问操作系统底层,是通过native方法(JNI)来访问。CAS底层通过Unsafe类实现原子性操作。

7.4 存在的问题

  • ABA问题
    • 什么是ABA问题?比如有一个 int 类型的值 N 是 1此时有三个线程想要去改变它:线程A ​​:希望给 N 赋值为 2线程B: 希望给 N 赋值为 2线程C: 希望给 N 赋值为 1​​此时线程A和线程B同时获取到N的值1,线程A率先得到系统资源,将 N 赋值为 2,线程 B 由于某种原因被阻塞住,线程C在线程A执行完后得到 N 的当前值2此时的线程状态线程A成功给 N 赋值为2线程B获取到 N 的当前值 1 希望给他赋值为 2,处于阻塞状态线程C获取当好 N 的当前值 2 ​​​​​希望给他赋值为1​​然后线程C成功给N赋值为1​最后线程B得到了系统资源,又重新恢复了运行状态,​在阻塞之前线程B获取到的N的值是1,执行compare操作发现当前N的值与获取到的值相同(均为1),成功将N赋值为了2。​在这个过程中线程B获取到N的值是一个旧值​​,虽然和当前N的值相等,但是实际上N的值已经经历了一次1到2到1的改变
      • 上面这个例子就是典型的ABA问题​怎样去解决ABA问题给变量加一个版本号即可,在比较的时候不仅要比较当前变量的值 还需要比较当前变量的版本号。Java中 AtomicStampedReference 就解决了这个问题
  • 循环时间长开销大在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。

CAS只能保证一个共享变量的原子操作

8. AbstractQueuedSynchronizer(AQS)

AQS抽象的队列式同步器,是一种基于状态(state)的链表管理方式。state 是用CAS去修改的。它是 java.util.concurrent 包中最重要的基石,要学习想学习 java.util.concurrent 包里的内容这个类是关键。 ReentrantLock​、CountDownLatcher、Semaphore 实现的原理就是基于AQS。想知道他怎么实现以及实现原理 可以参看这篇文章。

9. Future

在并发编程我们一般使用Runnable去执行异步任务,然而这样做我们是不能拿到异步任务的返回值的,但是使用Future 就可以。使用Future很简单,只需把Runnable换成FutureTask即可。使用比较简单,这里不多做介绍。

10. 线程池

如果我们使用线程的时候就去创建一个线程,虽然简单,但是存在很大的问题。如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。线程池通过复用可以大大减少线程频繁创建与销毁带来的性能上的损耗。

由Executors使用工厂方法创建特定类型的ThreadPool,查看Executor源码:

public class Executors {
    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
}

可以看到其实各个ThreadPool都是由ThreadPoolExecutor实现的,只是根据不同的参数创建不同类型的线程池。

Java中线程池的实现类 ThreadPoolExecutor,其构造函数的每一个参数的含义在注释上已经写得很清楚了,这里几个关键参数可以再简单说一下

  • corePoolSize:核心线程数即一直保留在线程池中的线程数量,即使处于闲置状态也不会被销毁。要设置 allowCoreThreadTimeOut 为 true,才会被销毁。
  • maximumPoolSize:线程池中允许存在的最大线程数
  • keepAliveTime:非核心线程允许的最大闲置时间,超过这个时间就会本地销毁。
  • workQueue:用来存放任务的队列。
    • SynchronousQueue:这个队列会让新添加的任务立即得到执行,如果线程池中所有的线程都在执行,那么就会去创建一个新的线程去执行这个任务。当使用这个队列的时候,maximumPoolSizes一般都会设置一个最大值 Integer.MAX_VALUE
    • LinkedBlockingQueue:这个队列是一个无界队列。怎么理解呢,就是有多少任务来我们就会执行多少任务,如果线程池中的线程小于corePoolSize ,我们就会创建一个新的线程去执行这个任务,如果线程池中的线程数等于corePoolSize,就会将任务放入队列中等待,由于队列大小没有限制所以也被称为无界队列。当使用这个队列的时候 maximumPoolSizes 不生效(线程池中线程的数量不会超过corePoolSize),所以一般都会设置为0。
    • ArrayBlockingQueue:这个队列是一个有界队列。可以设置队列的最大容量。当线程池中线程数大于或者等于 maximumPoolSizes 的时候,就会把任务放到这个队列中,当当前队列中的任务大于队列的最大容量就会丢弃掉该任务交由 RejectedExecutionHandler 处理。

转载自 《Java并发编程,你需要知道的》

java全网最强并发系列教程 源码 https://github.com/javanan/Java-concurrency Java并发系列(1)并发编程的优缺点 简介: 一直以来,硬件的发展极其迅速,也有一个很著名的"摩尔定律",可能会奇怪明明讨论的是并发编程为什么会扯到了硬件的发展,这其中的关系应该是多核CPU的发展为并发编程提供的硬件基础。摩尔定律并不是一种自然法则或者是物理定律,它只是基于认为观测数据后,对未来的一种预... 阅读详情

相关推荐

Java并发编程札记-目录

本目录会随着专栏的更新而更新。 Java并发编程札记-目录 Java并发编程札记-(一)基础-01基本概念 Java并发编程札记-(一)基础-02创建线程 Java并发编程札记-(一)基础-03线程的生命周期 Java并发编程札记-(一)基础-04Thread详解 Java并发编程札记-(一)基础-05线程安全问题 Java并发编程札记-(一)基础-06synchronized详解 Java并

潘威威的博客 4839

volatile-内存屏障

内存屏障(也称内存栅栏,屏障指令等,是一类同步屏障指令,是CPU或编译器在对内存随机访问的操作中的一个同步点,使得此点之前的所有读写操作都执行后才可以开始执行此点之后的操作),避免代码重排序。内存屏障其实就是一种JVM指令,Java内存模型的重排规则会要求Java编译器在生成JVM指令时插入特定的内存屏障指令,通过这些内存屏障指令,volatle实现了Java内存模型中的可见性和有序性(禁重排),但volatile无法保证原子性。处理器在读屏障之后的读操作,都在读屏障之后执行。...

weixin_46662378的博客 1239

发票OFD格式转换成PDF

发票OFD格式转换成PDF

Be_insighted的博客 930

JUC 四. volatile 与内存屏障

目录一. volatile 基础二. 内存屏障三. volatile 与内存屏障四. volatile 变量的读写过程通过了解 volatile 的读写过程了解为什么不具备原子性五. 如何正确使用 volatile六. 总结 一. volatile 基础 前面我看了解了JMM内存模型,内存又分为主内存与本地内存(也就是缓存),线程读数据是主内存的,而修改数据是先修改缓存,然后由缓存刷出到主内存中,假设在刷出前其它线程进来可能读取到老数据,出现脏读等问题 volatile 基于JMM"先行发生原则happe

qq_29799655的博客 935

OneNet平台MQTT连接避坑指南:C语言Token计算实战(附完整代码)

本文详细解析了OneNet平台MQTT连接中的Token计算机制,提供了C语言实现的完整代码和实战指南。通过HMAC算法和Base64编码,开发者可以高效生成安全凭证,避免常见连接问题,适用于物联网设备开发。

weixin_29193359的博客 460

Mid-360激光雷达与Fast-LIO2实战:从环境搭建到实时点云建图

本文提供Livox Mid-360激光雷达与Fast-LIO2算法从零开始的实战教程。详细介绍了在Ubuntu和ROS环境下进行系统配置、依赖安装、硬件连接与网络设置的完整流程,并指导如何运行算法实现实时点云建图与可视化,最后总结了关键参数调优与常见问题排查方法。

weixin_29300241的博客 152

volatile原理(内存屏障)

volatile 场景 一个线程写,其他线程读的情况 double-check-lock时,synchronized同步代码块外共享变量的指令重排序问题 同步机制 volatile 是 Java 虚拟机提供的轻量级的同步机制(三大特性) 保证可见性 不保证原子性 保证有序性(禁止指令重排) 性能:volatile 修饰的变量进行读操作与普通变量几乎没什么差别,但是写操作相对慢一些,因为需要在本地代码中插入很多内存屏障来保证指令不会发生乱序执行,但是开

2301_79437276的博客 2327

详解大模型微调数据集构建方法(持续更新)

本文详细介绍了大模型微调数据集构建方法,希望能对学习大模型的同学们有所帮助。 文章目录 1. 前言 2. 微调数据集构建方法 2.1 方法一 2.2 方法二 2.3 方法三 2.4 方法四 2.5 方法五

herosunly的博客 28万+

volatile内存屏障及实现原理分析

volatile实现原理分析 并发编程系列汇总初识volatilevolatile如何保证可见性可见性的本质硬件层面总线锁缓存锁MESI(缓存一致性协议)CPU工作流程MESI协议带来的问题CPU层面的内存屏障 JVM层面JMM(Java内存模型)JMM抽象模型结构JM...

weixin_47303690的博客 1561

PSINS工具箱学习(四)捷联惯导更新算法

原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning。

实践出真理,接毕设/课设项目开发指导 605

38.XDMA寄存器详解2-H2C、C2H通道寄存器组剖析

目录 1.上节回顾 2. H2C寄存器剖析 2.1 H2C通道标识寄存器(0x00) 2.2 H2C通道控制寄存器(0x04) 2.3 H2C通道状态寄存器(0x40) 2.4 H2C通道完成描述符数量寄存器(0x48) 2.5 H2C通道对齐寄存器(0x4C) 2.6 H2C通道查询模式回写地址寄存器(0x88、0x8C) 2.7 H2C通道中断掩码寄存器(0x90)​ 2.8 H2C通道性能监视控制寄存器(0xC0) 2.9 H2C通道周期计数性能寄存器(0xC4、0xC8) 2

一个早起的程序员 5204

详述Java内存屏障,透彻理解volatile

一般来说内存屏障分为两层:编译器屏障和CPU屏障,前者只在编译期生效,目的是防止编译器生成乱序的内存访问指令;后者通过插入或修改特定的CPU指令,在运行时防止内存访问指令乱序执行

Java 技术专栏,从入门到精通,熟悉企业级开发 2181

使用Matlab simulink的PLC coder功能进行算法搭建与处理

使用的案例如下: Anti-Windup PID Control Demonstration with Feedforward Control 将其中的PID块生成SCL语言再导入TIA 使用的平台如下: Matlab 2019b TIA portal 15.1 应用:可以在PLC中搭载一些并不方便使用的,或者比较难使用的算法 步骤如下: 首先打开案例,案例地址我放在最下面,点击Run运行仿真,必...

苦走一口田 1万+

二、Java基础系列之并发包

CompletionService ExecutorCompletionService = Executor + LinkedBlockingQueue 典型的适配器模式 线程池 = Runnable + Executor AbstractExecutorService submit execute Future ForkJoinTask Fu...

大道至简 627

InVEST模型 | HAbitat quality模块计算生境质量

 本文详细介绍使用InVEST模型中HAbitat quality模块计算生境质量,包含各个参数的含义、所需数据、数据处理以及需要各个参数注意的地方等过程。

地理空间科学的博客 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

科普文:Java基础系列之【并发编程二java线程基础】

与之对应的就是用户线程,用户线程就可以认为是系统的工作线程,它会完成整个系统的业务操作。InterruptedException 不是运行时异常,也就是说程序必须捕获并且处理它,当线程在sleep() 休眠时,如果被中断,这个异常就会产生。守护线程是一种特殊的线程,就和它的名字一样,它是系统的守护者,在后台默默地守护一些系统服务,比如垃圾回收线程,JIT线程就可以理解守护线程。,它会一直阻塞当前线程,知道目标线程执行完毕((别的线程得等调用了join的线程执行完)。方法,会抛出异常,被catch捕获。

为无为,事无事,味无味。 943

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java并发编程系列教程---并发基础(二)

Java线程 3.1线程的创建和运行 方法1 //创建线程对象 Thread t = new Thread() { public void run() { // 要执行的任务 } }; // 启动线程 t.start(); 方法2 Runnable runnable = new Runnable() { public void run() { // 要执行的任务 } }; // 创建线程对象 Thread t

ABCchinatea的博客 221

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

《Java后端知识体系》系列之并发编程基础(二)

并发编程二 多线程并发编程 线程安全问题 共享变量的内存可见性 synchronized volitile Java原子性操作 CAS操作 Unsafe类 Java指令重排序 锁 悲观锁与乐观锁 公平锁与非公平锁 可重入锁 自旋锁

qq_40126996的博客 220

科普文:Java基础系列之【并发编程二java线程状态:BLOCKED、WAITING、TIMED_WAITING】

前面有梳理java的线程状态和操作系统的线程状态:java的线程调用的就是操作系统的线程接口,其线程状态只是将Ready和Running统称为Runnable。因为java线程的start底层调用的native方法start0是操作系统提供的方法,start之后,即将线程交给操作系统来调度。详细可以看:Java的Thread.State枚举,共有六个状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。

为无为,事无事,味无味。 1408

java知识体系精讲系列二(进阶篇) -- 面试指南

系统讲解了 java 中高级知识体系,包括:JVM 与性能调优, JAVA 并发编程和JUC, JAVA 网络编程知识体系。

yun_zhonghe02的专栏 979

Java并发学习系列-绪论

最近在系统的学习Java并发(concurrent),遂将学习所得整理成博文,作为今后参考的依据。 内容简述 基本概念与发展历史 Thread的线程方法与状态转换 JMM、指令重排、happens-before原则、原子性、可见性与有序性 易变类型关键字volatile 同步关键字synchronized 显式锁Lock 原子变量Atomic 线程本地变量ThreadLocal 倒计时门...

韩超的博客 (hanchao5272) 8786

Java并发系列(二)

Java并发系列(二)

Love Peace 2020

【Java并发编程系列】- Java并发编程基础

默认情况下Java进程需要等其中所有线程全结束才会结束,但若设置某线程为守护线程,则在其他线程全结束的情况下,即使守护线程还没执行完,Java进程也会停止,守护线程自动被结束。多线程时,每个线程都会维护自己的栈和栈帧,每个线程只能有一个活动栈帧,对应当前正在执行的方法,方法执行完会返回到栈帧中方法出口地址的位置,然后从栈中pop出栈。直接使用 run 的方式,在mian中直接调用t1线程的run方法,则会是main方法调用执行run方法中的内容,t1会一直处于在新建状态。

m0_68383079的博客 788

Java并发系列二《并发知识储备》

系列文章目录 Java并发系列一《线程池原理》 Java并发系列三《ReentrantLock》 目录 系列文章目录 前言 一、CAS是什么? 二、AQS是什么? 三、 公平锁、非公平锁区别? 前言 本文总结学习并发知识需要用到的知识点,如:CAS 、AQS队列、公平锁、非公平锁等概念 一、CAS是什么? CAS全称为:Compare and Swap,比较并交换。在Java中,CAS主要是由sun.misc.Unsafe这个类通过调用native方法实现。如下设置state所示

天地一蜉蝣 778

Java并发编程系列之一并发理论基础

Java并发编程系列之一并发理论基础 本系列文章开始Java并发编程的进阶篇的学习,为了初学者对多线程的初步使用有基本概念和掌握,前置知识会对一些基础篇的内容进行介绍,以使初学者能够丝滑入戏。 多线程学习,真正的难点不在于多线程程序的逻辑有多复杂,而在于理清J.U.C包中各个多线程工具类之间的关系、特点及其使用场景,学习应该是从整体到局部、高屋建瓴,这对学习任何知识都至关重要。 站在上帝视角,以全局视野,抽丝剥茧,深入每个并发编程的各个包及APi的底层实现。 概览 下图为并发编程包含的所有知识。读者大致浏览

程序员田同学的博客 587

Java进阶篇之并发基础

Java并发编程是现代软件开发的重要组成部分,尤其在多核处理器的环境下,能够充分利用计算资源,提升应用的性能和响应能力。本文将专注于Java并发的基础概念,重点介绍线程的创建、线程生命周期以及线程安全问题。线程是程序执行的最小单位,是操作系统能够进行运算调度的最小单位。一个标准的Java应用程序至少有一个线程,即主线程。线程允许程序在多个路径上同时执行,从而提高效率。线程安全是指当多个线程访问共享资源时,不会导致数据不一致或其它错误。

小码农的博客 1319
上一篇: Java并发系列之基础一
下一篇: 远程连接阿里云的redis
章 鱼
博客等级 码龄10年 203粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值