并发编程入门

最近在学习慕课网的高并发课程。为面试做准备。这门课程个人感觉讲的不错。有理论,有实践。最好结合《Java并发编程实战》这本书来看。当时看书的时候各种云里雾里。后来看了这门课之后,好多东西感觉都懂了。所以说有一个能用实例把知识讲明白的老师很难得。

在开始真正的讲解以前,我们实现一个简单的场景-实现一个计数功能 : 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的,且每次都有可能不一样。

从上面试了中可以看出,在多线程并发的情况下执行一个简单的累加操作,出错的概率非常的高。这时候需要考虑,并发情况下到底应该如何编码。

并发与高并发的基本概念

1.并发

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

2.高并发

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

3.基本概念

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

猜你喜欢

转载自blog.csdn.net/q_all_is_well/article/details/85450637