前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >并发挑战(一)

并发挑战(一)

作者头像
Java架构师必看
发布于 2021-05-14 02:24:48
发布于 2021-05-14 02:24:48
29000
代码可运行
举报
文章被收录于专栏:Java架构师必看Java架构师必看
运行总次数:0
代码可运行

并发挑战(一)

强烈推介IDEA2020.2破解激活,IntelliJ IDEA 注册码,2020.2 IDEA 激活码

并发的目的

并发编程的目的是为了让程序运行的更快一点,但是,并不是启动更多的线程就可以让程序执行的效率更高,运行更快。进行并发编程时,如果希望通过多线程执行让程序变得更快,会面临非常大的挑战,如:上下文切换、死锁以及受限制于阴间和软件的资源限制等问题。

上下文切换

单核处理器也支持多线程去执行代码,CPU是通过给每个程序分配时间片来实现并行机制。时间片是CPU分配给各个线程的时间。时间片非常短,CPU通过不断切换线程执行,让我们感觉上是并发执行。 CPU通过时间片分配算法来循环执行任务,当前时间片执行完成之后,记住当前任务执行的状态,以便于下次切换回来的时候,加载这个状态,继续执行,所以任务从保存到再加载的过程就是一次上下文切换。 但是,上下文切换会影响多线程的执行速度。 下面代码演示的是串行和并发执行并累加操作的时间,但是并发执行一定比串行快吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ConcurrencyTest {
    private static final long count = 10000l;

    public static void main(String[] args) throws InterruptedException {
        concurrency();
        serial();
    }

    private static void serial() {
        long start = System.currentTimeMillis();
        int a = 0;
        for (long i = 0; i < count; i++) {
            a += 5;
        }
        int b = 0;
        for (long i = 0; i < count; i++) {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        System.out.println("serial:" + time+"ms,b="+b+",a="+a);
    }

    private static void concurrency() throws InterruptedException {
        long start = System.currentTimeMillis();//获取当前时间戳
        Thread thread = new Thread(() -> {
            int a = 0;
            for (long i = 0;i < count;i++){
                a += 5;
            }
        });
        thread.start();
        int b = 0;
        for (long i = 0;i < count;i++) {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        thread.join();//调用线程等待,只有该线程执行完成之后,才能往下执行
        System.out.println("concurrency :" + time+"ms,b="+b);
    }
}

答案是未必

如图所示,并发累加操作如过没用超过百万,执行速度要比串行的慢。主要是因为上下文切换的开销.

减少上下文切换

减少上下文切换的方式主要有

  • 无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程在处理数据时,可以用一些方法来避免使用锁,例如:讲数据的id按照hash算法取模分段,不同的线程处理不同段的数据
  • CAS算法:Java的Atomic包使用CAS算法来更新数据,而不需要加锁
  • 使用最小线程:避免创建没必要的线程,减少处于等待状态的线程
  • 使用协程:在单线程中实现多任务调度,并在单线程中维持多个线程的切换

原文链接:https://gper.club/articles/7e7e7f7ff7g5agc3g68

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
java 并发编程之上下文切换
      CPU给每个线程分配cpu时间片来实现多线程的机制。时间片是cpu给每个线程分配的时间。因为时间片非常短,所以cpu通过不停的切换线程执行,让我们感觉多个线程是同时执行的,时间片一般为几十毫秒。
爱明依
2019/03/12
4240
并发编程初探
并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行。在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临许多挑战,比如上下文切换的问题、死锁的问题,以及受限于硬件和软件的资源限制问题,本章会介绍几种并发编程的挑战以及解决方案。
JavaEdge
2022/11/29
3330
并发编程初探
Java并发编程的艺术[1]
昨天阅读翻译了CompletableFuture的源码,目前百度,有道,基本是翻译效果一般,Google翻译比较准确,源码有很多注释,写个小测试类将其去掉,另外获得了《Java并发编程的艺术》PDF版,因为需要测试demo,就要转word,又找了个小测试类转成word,效果不错。参考《Java并发编程的艺术》
疯狂的KK
2020/07/31
4820
Java并发编程的艺术[1]
多线程一定就快吗?
要了解并发编程,首先要懂得与并行这个概念进行区分。并行是指两个事件同时进行,并发是CPU切换速度快,看起来像是每个任务同时进行一样。多线程是实现并发编程的一种方式,假设一个场景,在广州地铁高峰时段,一群人涌进地铁里,在不同的闸机口刷卡进去。在这个场景里,进地铁就是任务,每个人可以看出是并发的,而多个刷卡闸机口就是多线程。
崔笑颜
2020/06/08
1.2K0
面试 | 多线程中的上下文切换
双十一前的一个多月,所有的电商相关的系统都在进行压测,不断的优化系统,我们的电商ERP系统也进行了一个多月的压测和优化的过程,在这其中,我们发现了大量的超时报警,通过工具分析,我们发现是cs指标很高,然后分析日志,我们发现有大量wait()相关的Exception,这个时候我们怀疑是在多线程并发处理的时候,出现了大量的线程处理不及时导致的这些问题,后来我们通过减小线程池最大线程数,再进行压测发现系统的性能有了不小的提升。
故里
2020/11/25
2.1K0
面试 | 多线程中的上下文切换
理解上下文切换带来的性能影响
  在多任务操作系统中,为了提高CPU的利用率,可以让当前系统运行远多于CPU核数的线程。但是由于同时运行的线程数是由CPU核数来决定的,所以为了支持更多的线程运行,CPU会把自己的时间片轮流分给其他线程,这个过程就是上下文切换。   导致上下文切换的原因有很多,比如通过wait()、sleep()等方法阻塞当前线程,这时CPU不会一直等待,而是重新分配去执行其他线程。当后续CPU重新切换到当前线程时,CPU需要沿着上次执行的指令位置继续运行。因此,每次在CPU切换之前,需要把CPU寄存器和程序计数器保存起来,这些信息会存储到系统内核中,CPU再次调度回来时会从系统内核中加载并继续执行。简而言之,上下文切换,就是CPU把自己的时间片分配给不同的任务执行的过程。
向着百万年薪努力的小赵
2022/12/02
1.4K0
理解上下文切换带来的性能影响
谈谈多线程的上线文切换
我们知道,在并发程序中,并不是启动更多的线程就能让程序最大限度地并发执行。线程数量设置太小,会导致程序不能充分地利用系统资源;线程数量设置太大,又可能带来资源的过度竞争,导致上下文切换带来额外的系统开销,今天我们就来谈下线程的上线文切换。
架构狂人
2023/08/16
2340
谈谈多线程的上线文切换
并发面临的问题小结
在单核CPU机器下,也可以支持并发多线程执行代码,这个时候CPU会为每一个线程分配对应的时间片,通过在指定的时间片内执行对应的线程程序代码,时间片一到,线程再继续争抢CPU资源重复上述动作,CPU需要不断地进行来回切换上下文以便能够执行到争抢到资源的线程,开发人员可以在linux系统下通过vmstat查看的context switch,即cs表示上下文
小坤探游架构笔记
2020/03/10
6850
并发面临的问题小结
Java并发编程的艺术,解读并发编程的优缺点
时间片是CPU分配给各个线程的时间,因为时间非常短,所以CPU不断通过切换线程,让我们觉得多个线程是同时执行的,时间片一般是几十毫秒。 而每次切换时,需要保存当前的状态起来,以便能够进行恢复先前状态,而这个切换时非常损耗性能, 过于频繁反而无法发挥出多线程编程的优势。 通常减少上下文切换可以采用无锁并发编程,CAS算法,使用最少的线程和使用协程。
李红
2019/05/29
5250
Java并发编程的艺术(一)
并发编程的目的是为了让程序运行的更快,但是并不是启动更多的线程就能让程序更大限度地并发执行。--例如上下文切换的问题,死锁的问题,受限于软件和硬件的资源问题。
JathonKatu
2020/10/27
5860
Java并发编程的艺术(一)
java并发编程的艺术笔记第一章——并发编程的挑战
单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程是同时执行的,时间片一般是几十毫秒(ms)
会跳舞的机器人
2018/09/03
3180
Redis为什么这么快?
说起当前主流NoSql数据库非 Redis 莫属。因为它读写速度极快,一般用于缓存热点数据加快查询速度,大家在工作里面也肯定和 Redis 打过交道,但是对于Redis 为什么快,除了对八股文的背诵,好像都还没特别深入的了解。
敖丙
2022/01/13
7980
Redis为什么这么快?
快速掌握并发编程---深入了解volatile
今天聊得这个volatile是一个轻量级的synchronized,它在多线程开发中保证了共享变量的“可见性”。
田维常
2020/11/03
6070
快速掌握并发编程---深入了解volatile
详解并发编程的优缺点
一直以来并发编程对于刚入行的小白来说总是觉得高深莫测,于是乎,就诞生了想写点东西记录下,以提升理解和堆并发编程的认知。为什么需要用的并发?凡事总有好坏两面,之间的trade-off是什么,也就是说并发编程具有哪些缺点?以及在进行并发编程时应该了解和掌握的概念是什么?这篇文章主要以这三个问题来谈一谈。
本人秃顶程序员
2019/05/05
9000
详解并发编程的优缺点
Java并发编程的艺术(一)——并发编程需要注意的问题
并发是为了提升程序的执行速度,但并不是多线程一定比单线程高效,而且并发编程容易出错。若要实现正确且高效的并发,就要在开发过程中时刻注意以下三个问题: 上下文切换 死锁 资源限制 接下来会逐一分析这三个问题,并给出相应的解决方案。 问题一:上下文切换会带来额外的开销 线程的运行机制 一个CPU每个时刻只能执行一条线程; 操作系统给每条线程分配不同长度的时间片; 操作系统会从一堆线程中随机选取一条来执行; 每条线程用完自己的时间片后,即使任务还没完成,操作系统也会剥夺它的执行权,让另一条线程执行 什么是“上下文
大闲人柴毛毛
2018/03/09
7860
了解Java并发编程基础!超详细!
Java程序天生就是多线程程序,因为执行main()方法的是一个名称为main的线程。下面使用JMX来查看一个普通的Java程序包含哪些线程,代码如下。
程序员的时光001
2021/04/02
3370
【JUC基础】17. 并发编程常见问题
多线程固然可以提升系统的吞吐量,也可以最大化利用系统资源,提升相应速度。但同时也提高了编程的复杂性,也提升了程序调试的门槛。今天就来汇总一些常见的并发编程中的问题。
有一只柴犬
2024/01/25
1650
【JUC基础】17. 并发编程常见问题
5.串行执行和并发执行的效率对比
利用线程来并发执行的方法效率较高,此程序运行结果为: 可以看待时间为:3858ms
小雨的分享社区
2022/10/26
4280
5.串行执行和并发执行的效率对比
JAVA并发之加锁导致的活跃性问题剖析
但是加锁也为我们带来了诸多问题 如:死锁,活锁,线程饥饿等问题 这一章我我们主要处理锁带来的问题. 首先就是最出名的死锁
Java宝典
2021/01/14
4950
JAVA并发之加锁导致的活跃性问题剖析
Java线程面试题:什么是线程上下文切换?为什么要减少上下文切换?
线程上下文切换是指操作系统为了能够让多个线程并发执行,在运行一个线程前,需要保存当前线程的 CPU 寄存器、程序计数器、栈指针和其他硬件上下文信息,以便于在恢复该线程时还原到之前的状态。而将这些信息保存起来、加载其他线程运行所需的上下文信息,然后再切换到该线程继续执行的过程就被称为线程上下文切换。
GeekLiHua
2025/01/21
1650
相关推荐
java 并发编程之上下文切换
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验