zoukankan      html  css  js  c++  java
  • java并发编程小结

    旭日Follow_24 的CSDN 博客 ,全文地址请点击:

    https://blog.csdn.net/xuri24/article/details/82078467

    线程简介:

    线程是操作系统调度的最先单元,进程:线程=1:N 关系,也就是说一个进程可以创建多个线程,至少包含一个线程。多线程可以最大限度的使用CPU和维护各线程之间的并发进行关系等。

    一、concurrent并发包

    • locks部分:显式锁(互斥锁和速写锁)相关;
    • atomic部分:原子变量类相关,是构建非阻塞算法的基础;
    • executor部分:线程池相关;
    • collections部分:并发容器相关;
    • tools部分:同步工具相关,如信号量、闭锁、栅栏等功能;

    二、volatile变量

    volatile为声明共享变量提供了读/写操作同步,即多个线程同时对变量进行读写操作,每次线程操作的变量值都将会是最新的那个值。例如:A线程对变量进行写操作,同时B线程对变量进行读操作,传统的方式操作会出现脏读(即B线程读到不是A线程更新的值),使用volatile声明该变量后,B线程读到的将是A线程更新后提交到主内存中最新的值。

    三、syncronized同步变量

    syncronized是同步关键字,并发编程中一个重要的关键字属性。

    • 对于普通同步方法,锁是当前实例对象
    • 对于静态同步方法,锁是当前类的Class对象
    • 对于同步方法块,锁是Syncronized括号里配置的对象

    当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时候,必须释放锁。

    四、lock锁

    Lock接口,锁用来控制多个线程访问共享资源的方式,一个锁能够防止多个线程同时访问共享资源(读写锁例外)。与syncronized不同的是,lock是显式的获取和释放锁,syncronized是隐式的jvm内置的关键字。

    • void lock()  获取锁方法
    • lockInterruptibly()throws interruptedException 可中断地获取锁,与lock不同的是,该方法在获取的过程中可中断线程
    • boolean tryLock() 尝试非阻塞的获取锁,获取到返回true,否则返回false
    • boolean tryLock(long time,TimeUnit unit)throws InterruptedException 超时获取锁,3种情况返回:1、当前线程在超时时间内获得了锁 2、当前线程在超时时间内被中断 3、超时时间结束,返回false
    • void unlock() 释放锁方法
    • Condition newCondition() 获取等待通知组件,该组件和当前的锁绑定,当前线程只有获得了锁,才能调用该组件的wait()方法,调用后当前线程释放锁

    队列同步器AbstractQueuedSynchronizer(AQS),用来构建锁或其他同步组件的基础框架,使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。

    • getState() 获取当前同步状态
    • setState(int newState) 设置当前同步状态
    • compareAndSetState(int expect,int update) 使用CAS设置当前状态,该方法能够保证状态设置的原子性

    重入锁ReentrantLock,支持一个线程对资源的重复加锁,支持获取锁的公平和非公平性选择。

    • 实现重进入
    • 线程再次获取锁
    • 锁的最终释放
    • 公平和非公平获取锁
    1. 读写所
    2. LockSupport工具
    3. Condition接口

    五、java并发容器和框架

    ConcurrentHashMap线程安全且高效的HashMap。并发编程中HashMap可能会导致线程死循环,HashTable效率又非常低下。

    HashMap中的put操作,Entry链表会形成环形数据结构后,Entry的next节点将永远不为空,则产生死循环。

    ConcurrentHashMap是由:Segment数组结构和HashEntry数组结构组成,Segment是一种可重入锁(ReentrantLock),HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含了一个Segment数组,一个Segment里包含了一个HashEntry数组,每个Segment守护着HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获取它对应的Segment锁。

    六、Java线程池

    线程池多用于并发框架,线程池的好处:

    1. 降低资源消耗
    2. 提高相应速度
    3. 提高线程的可管理性

    实现原理,线程池的处理流程:

    1. 线程池判断核心线程里的线程是否都在执行任务,如果不是则创建一个新的工作线程来执行任务,如果核心线程池里的线程都在执行任务,则进入下个流程。
    2. 线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里,如果工作队列满了,则进入下个流程。
    3. 线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。

    线程池的使用:

    1. 创建线程池ThreadPoolExecutor new ThreadPoolExecutor(corePoolsize ,maximumPoolSize,keepAliveTime,milliseconds,runnableTaskQueue,handler);
    • corePoolsize  线程池的基本大小,提交一个任务到线程池后,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建。
    • runnableTaskQueue 任务队列,用于保存等待执行的任务的阻塞队列
    • maximumPoolSize 线程池最大的数量,允许创建的最大线程数,如果队列已满,并且以创建的线程数小于最大线程数,则线程池会再创建新的线程来执行任务。
    • keepAliveTime 线程活动保持时间,线程池工作线程空闲后,保持存活的时间。
    • handler 饱和策略,当队列和线程池都满了,则线程池处于饱和状态,必须采取策略来处理提交的新任务:抛异常、只用调用者的所在线程来运行任务、丢弃队列里最近一个任务,执行当前任务、不处理,直接丢弃。

       2.向线程池提交任务

       3.关闭线程池

       4.配置线程池

       5.线程池的监控

    七、Executor框架

    Executor框架的常用的几个接口和子类

    Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command),

    ExecutorService:是一个比Executor使用更广泛的子类接口,其提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行状况返回Future的方法

    AbstractExecutorService:ExecutorService执行方法的默认实现

    ScheduledExecutorService:一个可定时调度任务的接口

    ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池

    ThreadPoolExecutor:线程池,可以通过调用Executors以下静态工厂方法来创建线程池并返回一个ExecutorService对象

    public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler) //后两个参数为可选参数

    参数说明:

    corePoolSize:核心线程数,如果运行的线程少于corePoolSize,则创建新线程来执行新任务,即使线程池中的其他线程是空闲的

    maximumPoolSize:最大线程数,可允许创建的线程数,corePoolSize和maximumPoolSize设置的边界自动调整池大小:

    corePoolSize <运行的线程数< maximumPoolSize:仅当队列满时才创建新线程

    corePoolSize=运行的线程数= maximumPoolSize:创建固定大小的线程池

    keepAliveTime:如果线程数多于corePoolSize,则这些多余的线程的空闲时间超过keepAliveTime时将被终止

    unit:keepAliveTime参数的时间单位

    workQueue:保存任务的阻塞队列,与线程池的大小有关:

      当运行的线程数少于corePoolSize时,在有新任务时直接创建新线程来执行任务而无需再进队列

      当运行的线程数等于或多于corePoolSize,在有新任务添加时则选加入队列,不直接创建线程

      当队列满时,在有新任务时就创建新线程

    threadFactory:使用ThreadFactory创建新线程,默认使用defaultThreadFactory创建线程

    handle:定义处理被拒绝任务的策略,默认使用ThreadPoolExecutor.AbortPolicy,任务被拒绝时将抛出RejectExecutorException

  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/Liuq-24/p/9695108.html
Copyright © 2011-2022 走看看