zoukankan      html  css  js  c++  java
  • 并发总结

    该文档从三个方面来总结并发:

    一,线程安全

    什么是线程安全?

    同一段代码多线程运行与单线程运行,每次结果都一样并且结果与预期一致,就是线程安全。换言之多线程并没有导致数据与预期不一致。

    简单例子:

    不安全的ArrayList添加元素。如果单线程添加元素,没有问题。如果有两个线程添加元素,A线程欲在position=0位置添加数字10,在还没有添加进去时,此时B线程也在添加数据,结果B把position=0位置数据添加为20,此时A线程工作position=0位置数据改为10。与预期不一致,预期ArrayList中有两个数据10,20.现在只有一个数据10。

    如何做到线程安全?

    synchronized关键字方案:

    通过将多线程共享的资源添加一把锁,这样每个线程访问共享资源就都是串行访问,不会出现线程不安全的问题。

    synchronized(lock){
          doSomething(resource)      
    }
    sychronized 示例

    synchronized底层如何实现?

    synchronized关键字在字节码层面上将其monitorenter,monitorexit两个成对原语。 

    二,线程可见性

    因为一个系统可能有多颗CPU,为了保证一个线程中对一个变量的修改,在另外一个线程中被看见,所以有了线程可见性的问题。一般采用volatile关键字实现。

    三,线程池

    Java基础中熟悉一种线程池框架就可以应对工作中90%的场景:Executor框架

    /**
         * Creates a new {@code ThreadPoolExecutor} with the given initial
         * parameters and default thread factory and rejected execution handler.
         * It may be more convenient to use one of the {@link Executors} factory
         * methods instead of this general purpose constructor.
         *
         * @param corePoolSize the number of threads to keep in the pool, even
         *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
         * @param maximumPoolSize the maximum number of threads to allow in the
         *        pool
         * @param keepAliveTime when the number of threads is greater than
         *        the core, this is the maximum time that excess idle threads
         *        will wait for new tasks before terminating.
         * @param unit the time unit for the {@code keepAliveTime} argument
         * @param workQueue the queue to use for holding tasks before they are
         *        executed.  This queue will hold only the {@code Runnable}
         *        tasks submitted by the {@code execute} method.
         * @throws IllegalArgumentException if one of the following holds:<br>
         *         {@code corePoolSize < 0}<br>
         *         {@code keepAliveTime < 0}<br>
         *         {@code maximumPoolSize <= 0}<br>
         *         {@code maximumPoolSize < corePoolSize}
         * @throws NullPointerException if {@code workQueue} is null
         */
        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }

    搞懂Executor只需要搞明白上面这个构造函数就可以。

    1. taskCount<=corePoolSize:用该线程池中缓存的线程去执行task
    2. taskCount>corePollSize && taskCount<maxPoolSize:新建线程(maxPoolSize-corePoolSize)来应对多余的task
    3. taskCount>maxPoolSize:多余的task的放到queue中等待,等待时间为keepAliveTime,如果超时采用RejectedExecutionHandler来处理
      • AbortPolicy
      • CallerRunsPolicy
      • DiscardOldestPolicy
      • DiscardPolicy

     该线程池还是非常清晰明白了。

    四,concurrent包内容

    该包下都是并发的好东西,拣上面比较重要的总结下

    Atomic

    满足原子的对各种数据类型的对象进行操作 

    locks

    queue

    并发组件

  • 相关阅读:
    Java中HashMap底层实现原理(JDK1.8)源码分析
    java io系列01之 "目录"
    数据结构与算法系列 目录
    Java 集合系列目录(Category)
    ls参数
    在PATH路径中添加新的路径
    目录相关的操作
    chmod
    属性类型
    ls -al
  • 原文地址:https://www.cnblogs.com/xinxinwang/p/4897522.html
Copyright © 2011-2022 走看看