美文网首页
2 并发编程初体验

2 并发编程初体验

作者: 十丈_红尘 | 来源:发表于2018-09-24 15:04 被阅读0次
    1️⃣前言

    在开始真正的讲解以前,我们实现一个简单的场景-实现一个计数功能

    计数功能 : CountExample

    @Slf4j
    public class CountExample {
        // 请求总数
        public static int clientTotal = 5000;
        // 同时并发执行的线程数
        public static int threadTotal = 200;
        public static int count = 0;
    
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            final Semaphore semaphore = new Semaphore(threadTotal);
            for (int index = 0; index < clientTotal ; index++) {
                exec.execute(() -> {
                    try {
                        semaphore.acquire();
                        add();
                        semaphore.release();
                    } catch (Exception e) {
                        log.error("exception", e);
                    }
                });
            }
            exec.shutdown();
            log.info("count:{}", count);
        }
    
        private static void add() {
            count++;
        }
    }
    

    计数功能 : MapExample

    @Slf4j
    public class MapExample {
        private static Map<Integer, Integer> map = Maps.newHashMap();
        // 请求总数
        public static int clientNum = 5000;
        // 同时并发执行的线程数
        public static int threadNum = 200;
    
        public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors.newCachedThreadPool();
            final Semaphore semaphore = new Semaphore(threadNum);
            for (int index = 0; index < clientNum ; index++) {
                final int threadNum = index;
                exec.execute(() -> {
                    try {
                        semaphore.acquire();
                        func(threadNum);
                        semaphore.release();
                    } catch (Exception e) {
                        log.error("exception", e);
                    }
                });
            }
            exec.shutdown();
            log.info("size:{}", map.size());
        }
    
        private static void func(int threadNum) {
            map.put(threadNum, threadNum);
        }
    }
    
    从上面两个demo的运行结果可以看出,并发情况下每一次的运行结果都是小于5000的,且每次都有可能会不一样(大家可以多尝试几次就会发现,值一直会小于5000且可能每次值都不一样),那么我们如果把两个demo同时允许的进程数修改为1又会是什么样的呢?
    CountExample运行结果 MapExample运行结果

    从以上实例中我们可以看到,当我们在多线程并发的情况下执行一个简单的累加操作,出错的概率非常的高,这个时候我们就需要思考一下并发环境下到底应该如何编码?到底有哪些手段可以保证并发下的结果是正确的?


    2️⃣并发与高并发的基本概念
    并发

    同时拥有两个或者多个线程,如果程序在单核处理上运行,多个线程将交替地换入或者换出内存,这些线程是同时"存在"的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上,此时,程序中的每个线程都将分配到一个处理器核上,因此可以同时运行;


    高并发

    高并发(High Concurreny)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求;


    基本概念

    单纯的说概念可能有点难以理解,我们来简单对比一下并发与高并发;当我们说多线程并发时我们谈论的是什么呢?其实更多的是讨论多个线程操作相同的资源,这个时候我们谈论的点多数情况下是落实在保证线程安全,合理分配或者使用资源上边;那么当我们谈论高并发时我们谈论的又是什么呢?高并发主要是指系统运行过程中短时间内要大量操作请求的情况,它主要发生在系统集中收到了大量的请求比如12306以及天猫的双十一;这种情况的发生会导致系统在这段时间内会执行大量的操作,例如对资源的请求对数据库的操作等等,如果高并发处理不好不仅仅会降低用户的体验度(请求时间变长)同时也有可能会导致系统宕机,严重的甚至会导致OOM异常 系统停止工作等情况;如果想要系统适应高并发的状态,就要从多个方面对系统进行优化,包括硬件 网络 系统架构以及开发语言的选取 数据结构的运用 算法的优化 数据库优化等等;这个时候我们谈论的更多的是如何提高现有程序的性能,更多的是对高并发场景提高一些解决方案 思路 手段;

    相关文章

      网友评论

          本文标题:2 并发编程初体验

          本文链接:https://www.haomeiwen.com/subject/hwocoftx.html