资讯专栏INFORMATION COLUMN

并发编程之并发编程的挑战

LeanCloud / 3435人阅读

摘要:关于并发编程,其目的就是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序更大限度的并发执行。对于软件资源限制考虑使用资源池将资源复用,例如数据库连接池等资源限制情况下进行并发编程根据不同的资源限制调整程序的并发度。

关于并发编程,其目的就是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序更大限度的并发执行。有哪些影响并发编程的因素呢?

一、文章导图

二、挑战 1、上下文切换

单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制,只是时间片的时间短,感觉CPU能同时处理多个任务。时间片一般是几十毫秒(ms)。
CPU通过时间片轮训的方式处理任务,当前任务执行一个时间片会切换到下一个任务。注意,当CPU从一个任务切换到另一个任务前,会保留上一个任务的状态,以便再切回来是可以继续执行。所以任务从保持状态到再加载的过程就是一次上下文切换

多线程执行耗时测试

电脑配置:单处理器双核8G内存
public class Demo1_1_1 {

    private static final long count = 1000000001;

    public static void main(String[] args) throws InterruptedException {
        // 注释一个进行执行
        concurrent();
//        serial();
    }

    /**
     * 并发执行
     */
    private static void concurrent() 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 --;
        }
        thread.join();
        System.out.println("concurrent time:" + (System.currentTimeMillis() - start) + "ms");

    }

    /**
     * 串行执行
     */
    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 --;
        }
        System.out.println("serial time:" + (System.currentTimeMillis() - start) + "ms");
    }

}
以上分别执行3次,取一个最大值和一个最小值

结果

循环次数 并行耗时/ms 串行耗时/ms
10万 66 - 90 2 - 4
100万 68 - 78 5 - 13
1000万 75 - 81 16 - 19
1亿 133 - 128 80 - 121
10亿 600 - 615 900 - 1000

分析
当并发执行不超过亿级别时,并行是比串行慢的,这就是因为线程有创建和上下文切换的开销。按理说多个线程执行应该比单线程慢,实际并非如此。

如何减少上下文切换

1、无所并发编程:多线程竞争锁时,会引发上下文切换
2、CAS算法:Java中的Atomic包使用CAS算法更新数据,无需加锁
3、使用最少线程:任务少,但线程多,导致很多线程都处于等待状态
4、协程:在线程里实现多线程的调度

2、死锁

java中的锁主要用来解决并发编程资源竞争的问题,如果编程不当,一旦产生死锁,便会导致系统功能不可用。

例如,有两个线程t1,t2;两个资源A,B;当出现,t1持有A资源,t2持有B资源时,t1尝试获取B资源,t2尝试获取A资源,此时,便会出现死锁的情况。

避免死锁的办法

1、避免一个线程同时获取多个锁
2、避免一个线程在锁内同时占有多个资源,尽力保证每个线程只占用一个资源
3、尝试使用定时锁,如lock.tryLock(timeout)

3、资源限制的挑战

什么是资源限制

资源限制指在进行并发编程时,程序的执行速度受限于计算机硬件资源或软件资源。
硬件资源包括:带宽的上传下载速度、硬盘读写速度和CPU的处理速度等
软件资源包括:线程池大小、数据库的连接数等

资源限制引发的问题

在并发编程中,代码执行速度加快的原则是将代码中的串行部分变成并行执行,但有可能由于资源限制问题,导致程序仍按串行执行,此时程序不仅不会变快,反而更慢,因为增加了上下文切换和资源调度的时间。

如何解决资源限制的问题

对于硬件资源限制:考虑使用集群方式并行执行程序。
对于软件资源限制:考虑使用资源池将资源复用,例如数据库连接池等

资源限制情况下进行并发编程

根据不同的资源限制调整程序的并发度。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75968.html

相关文章

  • 物联网高并发编程单台服务器最大并发TCP连接数

    摘要:对端,通过增加内存修改最大文件描述符个数等参数,单机最大并发连接数超过万甚至上百万是没问题的,国外公司在产品环境中已做到万并发 [TOC] 前言 曾几何时我们还在寻求网络编程中C10K问题的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了。 我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来说已经远远足够了,但是对于一些拥有很大用...

    leap_frog 评论0 收藏0
  • 【Java并发编程艺术】第一章读书笔记

    摘要:前言并发编程的目的是让程序跑的更快,但并不是启动更多的线程,这个程序就跑的更快。尽可能降低上下文切换的次数,有助于提高并发效率。死锁并发编程中的另一挑战是死锁,会造成系统功能不可用。 前言 并发编程的目的是让程序跑的更快,但并不是启动更多的线程,这个程序就跑的更快。有以下几种挑战。 挑战及方案 上下文切换 单核CPU上执行多线程任务,通过给每个线程分配CPU时间片的方式来实现这个机制。...

    马忠志 评论0 收藏0
  • 并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    supernavy 评论0 收藏0
  • 并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    ddongjian0000 评论0 收藏0
  • 并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    wangdai 评论0 收藏0

发表评论

0条评论

LeanCloud

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<