Java并发编程的艺术 -- Java并发编程的挑战(第一章)

简介: Java并发编程的挑战(第一章)
本文参考于《Java并发编程的艺术》

1、 总述

并发编程的目的为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行。在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题死锁的问题,以及受限于硬件和软件的资源限制问题

2、线程上下文切换

2.1、切换过程

CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换

2.2、 线程上下文切换的缺点

上下文切换会消耗大量时间,从而影响多线程的执行速度。

2.3、多线程一定快吗?

不一定。

原因因为线程有创建和上下文切换的开销

2.4、如何减少上下文切换?

  1. 无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。
  2. CAS算法:Java的Atomic包使用CAS算法来更新数据而不需要加锁
  3. 使用最少线程避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。
  4. 使用协程在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换协程不是进程也不是线程,而是一种特殊的函数,这个函数可以在某个地方挂起,也可以从挂起处继续执行。一个线程的多个协程是串行执行的,当一个协程执行时,其他协程必须挂起。使用协程不再需要陷入系统的内核态执行效率非常高没有线程切换的开销更不需要多线程的锁机制

3、死锁

3.1、 什么是死锁?

线程死锁描述的是这样一种情况多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被 无限期地阻塞,因此程序不可能正常终止。

3.2、 产生死锁的条件

1. 互斥条件:该资源任意一个时刻 只由一个线程占用
2. 请求与保持条件:一个进程因请求资源而 阻塞时对已获得的资源保持不放
3. 不剥夺条件: 线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
4. 循环等待条件:若干线程之间形成一种 头尾相接的循环等待资源关系

3.3、 如何预防死锁?

1. 破坏请求与保持条件一次性申请所有的资源
2. 破坏不剥夺条件 :占用部分资源的线程进一步申请其他资源时, 如果申请不到,可以主动释放它占有的资源
3. 破坏循环等待条件 :靠按序申请资源来预防。 按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。

3.4、 如何避免死锁?

避免死锁就是在资源分配时,借助于 算法(比如银行家算法)对资源分配进行计算评估,使其进入安全状态。

4、资源限制问题

4.1、什么是资源限制?

资源限制是指在进行并发编程时, 程序的执行速度受限于计算机硬件资源或软件资源

4.2、资源限制引发的问题

将代码执行速度加快的原则将代码中串行执行的部分变成并发执行,但是如果将某段串行的代码并发执行,因为受限于资源,仍然在串行执行,这时候程序不仅不会加快执行,反而会更慢因为增加了上下文切换和资源调度的时间

4.3、如何解决资源限制的问题?

  1. 对于硬件资源限制,可以考虑使用集群并行执行程序。既然单机的资源有限制,那么就让程序在多机上运行。
  2. 对于软件资源限制,可以考虑使用资源池将资源复用

4.4、在资源限制情况下怎样进行并发编程?

根据不同的资源限制调整程序的并发度,比如下载文件程序依赖于两个资源——带宽和硬盘读写速度。
相关文章
|
1月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
185 0
|
1月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
146 6
|
1月前
|
安全 前端开发 Java
从反射到方法句柄:深入探索Java动态编程的终极解决方案
从反射到方法句柄,Java 动态编程不断演进。方法句柄以强类型、低开销、易优化的特性,解决反射性能差、类型弱、安全性低等问题,结合 `invokedynamic` 成为支撑 Lambda 与动态语言的终极方案。
145 0
|
2月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
549 1
|
2月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
437 100
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
142 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
160 1
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
136 0
|
2月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
220 16
下一篇
oss云网关配置