并发编程系列之并发编程的认识

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发编程系列之并发编程的认识

前言

今天我们开始接触并发编程的讲解,首先我们要知道并发编程的目的是什么?一个目的,为了让程序员运行的更快,但是有一点我们要知道,并不是启动越多的线程就能让程序更大限度的并发执行,在并发编程的开发中,如果希望使用更多的线程来加快程序的运行,一般我们会面临下面几种挑战:上下文切换问题,死锁、以及受硬件和软件资源的限制问题,那么我们一个个来说下吧,让我们开始今天的并发编程之旅吧。

上下文切换

什么是上下文切换?

即使是单核处理器,也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给每个线程的时间,因为时间片很短,所以CPU通过不断的切换线程执行,给用户感官上造成多线程执行的状态。

CPU通过时间分配算法来执行任务,当前任务执行一个时间片后,就会切换到下个任务,此时,会保存切换前上个任务的状态,目的是下次切换回这个任务时,可以继续加载该任务的状态,我们把任务从保存到再加载的这个过程就称为是一次上下文切换。

多线程一定比单线程快?

答案是否定的,多线程环境下,因为线程有创建和上下文切换的时间开销,所以,多线程并不一定比单线程快;只能说在有限的资源环境下,线程数量达到某个值之前会比单线程处理速度快,超过这个值速度就会下降,甚至比单线程速度低,如下图:

并发编程系列之并发编程的认识

如何减少上下文切换?

减少上下文切换主要有如下几种方式:

  • **无锁并发编程**:多线程竞争锁时会引起上下文切换,所以多线程处理数据时,可以用一些方法避免使用锁,如将任务的编号按照Hash取模分段,不同线程处理不同段的任务,即将任务或者数据分块处理,各个线程处理独立的块;
  • **CAS算法**:Java提供Atomic包使用CAS算法更新数据,取代加锁;
  • **使用最少线程**:避免创建不需要的线程,如少量任务时创建大量线程,就会造成大部分线程处于等待状态,减少等待线程的创建;
  • **协程**:单线程环境下,实现多任务调度,并维持多个任务之间的切换;
  • CAS算法:Java提供Atomic包使用CAS算法更新数据,取代加锁;

    协程:单线程环境下,实现多任务调度,并维持多个任务之间的切换;

    死锁

    死锁最常见的就是两个线程之间相互持有对方的锁,都在等待对方释放,而造成死锁,使得两个线程一直处于等待状态,因此我们应该要避免这样的场景出现,主要可以从下面几个方面考虑:

  • 避免一个线程同时获取多个锁
  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
  • 尝试使用定时锁,使得锁能得到一个释放(由tryLock实现)
  • 对于数据库锁,加锁和解锁必须在一个数据库连接中,否则会出现解锁失败的情况

  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源

    对于数据库锁,加锁和解锁必须在一个数据库连接中,否则会出现解锁失败的情况

    资源限制

    什么是资源限制?

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

    硬件资源主要包括:带宽的上传/下载速度、硬盘的读写速度和CPU的处理速度

    软件资源主要包括:数据库的连接数和socket连接数等

    资源限制引发的问题?

    并发编程中通过将串行执行的代码改为并发执行来加快处理速度,但是如果将某段代码改为并发执行之后,由于受到资源限制,代码本质上仍然在串行执行,那么由于增加了上下文切换和资源调度的时间,程序的速度不仅不会加快,反正更慢。

    如何解决资源限制问题?

    硬件资源受限:可以考虑使用集群并发执行程序

    软件资源受限:可以考虑使用资源池将资源复用,最大化利用资源

    今天的内容只是个引言,后续我们会详细讲解并发编程细节,感谢关注,本文参考《并发编程的艺术》

    原文始发于微信公众号(Justin的后端书架):

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 并发编程系列之并发编程的认识


     上一篇
    并发编程系列之原子操作实现原理 并发编程系列之原子操作实现原理
    前言 上节我们讲了并发编程中最基本的两个元素的底层实现,同样并发编程中还有一个很重要的元素,就是原子操作,原子本意是不可以再被分割的最小粒子,原子操作就是指不可中断的一个或者一系列操作。那么今天我们就来看看在多处理器环境下Java是如何保证
    2021-04-05
    下一篇 
    并发编程系列之线程池工厂类——Executors 并发编程系列之线程池工厂类——Executors
    前言 上节讲了讲自定义线程池,今天我们来聊聊线程池框架,在实际开发中我们还是基本使用线程框架Executor给我们提供的一些工具类,Java提供的Executor都在JUC(java.util.concurrent)包下面,主要包括:
    2021-04-05