java并发编程小结

liuq-24      2022-04-13     729

关键词:

旭日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







《java并发编程的艺术》学习小结

java并发编程的艺术第一章并发编程的挑战上下文切换:cpu通过时间片让不同线程轮流运行,从线程状态保存到下一次线程运行这个过程就是一次上下文切换多线程并不一定比单线程快,因为多线程会有线程创建和上... 查看详情

并发编程学习小结

...量的需要,定制自己线程池的大小。虽然通过这个对并发编程已经有了一定的了解,但是个人认为自己目前对于java的并发编程只是局限于使用和浅层的了解阶段,在这里先对自己这段时间的学习做个总结。    首先... 查看详情

并发编程学习小结

...量的需要,定制自己线程池的大小。虽然通过这个对并发编程已经有了一定的了解,但是个人认为自己目前对于java的并发编程只是局限于使用和浅层的了解阶段,在这里先对自己这段时间的学习做个总结。    首先... 查看详情

并发编程学习小结

...量的需要,定制自己线程池的大小。虽然通过这个对并发编程已经有了一定的了解,但是个人认为自己目前对于java的并发编程只是局限于使用和浅层的了解阶段,在这里先对自己这段时间的学习做个总结。    首先... 查看详情

java并发编程:底层实现机制

一、volatile的应用1.volatile的定义与实现原理2.volatile的使用优化二、synchronized的应用1.锁的实现原理2.锁的对比2.1偏向锁2.2轻量级锁2.3锁的对比三、原子操作的实现原理1.术语2.处理器如何实现原子操作3.Java如何实现原子操作四、小... 查看详情

java编程入门小结

Java编程入门小结Java发展历史 1.oak:java的前身,1991年出现 2.基于C++开发的新语言,主要用于嵌入式开发 3.之后产生了HotJava浏览器Java的可移植性/跨平台性java源程序*.java由编译器编译生成*.class文件*.class文件可运行在... 查看详情

java编程入门小结

Java编程入门小结Java发展历史 1.oak:java的前身,1991年出现 2.基于C++开发的新语言,主要用于嵌入式开发 3.之后产生了HotJava浏览器Java的可移植性/跨平台性java源程序*.java由编译器编译生成*.class文件*.class文件可运行在... 查看详情

concurrenthashmap源码阅读小结(代码片段)

...hMap相关源码分析的文章链接:ConcurrentHashMap扩容分析拾遗并发编程——ConcurrentHashMap#addCount()分析并发编程——C 查看详情

java并发编程:核心理论

Java并发编程系列:Java并发编程:核心理论 Java并发编程:Synchronized及其实现原理Java并发编程:Synchronized底层优化(轻量级锁、偏向锁)Java并发编程:线程间的协作(wait/notify/sleep/yield/join)Java并发编程:volatile的使用及其原理... 查看详情

java并发编程之美

一、内容简介并发编程相比Java中其他知识点的学习门槛较高,从而导致很多人望而却步。但无论是职场面试,还是高并发/高流量系统的实现,却都离不开并发编程,于是能够真正掌握并发编程的人成为了市场迫切需求的人才。... 查看详情

java并发编程--并发编程线程基础(线程创建与运行线程通知与等待join/sleep/yield方法线程中断线程上下文切换死锁守护线程与用户线程threadlocal)

文章目录1.并发编程线程基础(上篇)1.1线程基础知识1.1.1程序1.2.2进程1.3.3线程1.3.4小结1.2线程创建与运行1.2.1继承Thread类方式的实现1.2.2实现Runnable接口的run方法方式1.2.3使用FutureTask的方式1.3线程通知与等待1.3.1wait(&#... 查看详情

java并发编程:synchronized及其实现原理

Java并发编程系列:Java并发编程:核心理论 Java并发编程:Synchronized及其实现原理Java并发编程:Synchronized底层优化(轻量级锁、偏向锁)Java并发编程:线程间的协作(wait/notify/sleep/yield/join)Java并发编程:volatile的使用及其原理... 查看详情

java并发编程

Java并发编程(一)之前看《ThinkingInJava》时,并发讲解的挺多的,自己算是初步了解了并发。但是其讲解的不深入,自己感觉其讲解的不够好。后来自己想再学一学并发,买了《Java并发编程实战》,看了一下讲的好基础、好多的理... 查看详情

java并发编程--并发编程线程基础(线程创建与运行线程通知与等待join/sleep/yield方法线程中断线程上下文切换死锁守护线程与用户线程threadlocal)(代码片段)

文章目录1.并发编程线程基础(上篇)1.1线程基础知识1.1.1程序1.2.2进程1.3.3线程1.3.4小结1.2线程创建与运行1.2.1继承Thread类方式的实现1.2.2实现Runnable接口的run方法方式1.2.3使用FutureTask的方式1.3线程通知与等待1.3.1wait(&#... 查看详情

juc高并发编程(代码片段)

...1.3.线程的状态1.3.1线程状态枚举类1.3.2.wait/sleep的区别1.4.并发与并行1.4.1.串行模式1.4.2.并行模式1.4.3.并发1.4.4.小结(重点)1.5.管程1.6.用户线程和守护线程2.Lock接口2.1.Synchronized2.1.1.Synchronized关键字回顾2.1.2.售票案例2.2.什 查看详情

juc高并发编程(代码片段)

...1.3.线程的状态1.3.1线程状态枚举类1.3.2.wait/sleep的区别1.4.并发与并行1.4.1.串行模式1.4.2.并行模式1.4.3.并发1.4.4.小结(重点)1.5.管程1.6.用户线程和守护线程2.Lock接口2.1.Synchronized2.1.1.Synchronized关键字回顾2.1.2.售票案例2.2.什 查看详情

『死磕java并发编程系列』并发编程工具类之countdownlatch(代码片段)

《死磕Java并发编程》系列连载中,大家可以关注一波:👍🏻『死磕Java并发编程系列』01十张图告诉你多线程那些破事『死磕Java并发编程系列』02面试官:说说什么是Java内存模型?『死磕Java并发编程系列... 查看详情

『死磕java并发编程系列』并发编程工具类之countdownlatch(代码片段)

《死磕Java并发编程》系列连载中,大家可以关注一波:👍🏻『死磕Java并发编程系列』01十张图告诉你多线程那些破事『死磕Java并发编程系列』02面试官:说说什么是Java内存模型?『死磕Java并发编程系列... 查看详情