1.1 Java并发编程的一些概念
并发编程的一些概念
同步和异步
同步:
同步方法必须等到方法调用返回后,才能继续后继的行为。也就是说,同步方法执行时,如果没有返回,则后面的方法是执行不到的。同步方法调用,调用过程中可能出现阻塞和等待。
比如说,java读取控制台输入就是同步方法。
异步:
异步方法调用后立即返回,可以立即执行后继的方法。异步方法的返回结果,采用通知的方式来告知调用者。异步方法调用,调用过程中不会出现阻塞和等待。
举个例子:js的ajax方法就默认是异步调用的,执行后马上返回,继续执行下面的代码。如果你想操作结果,就需要传递success方法。那么异步方法调用完成后,会通知你返回结果并调用success方法。也就是说异步方法不会马上得到结果的。
并发和并行
并发 :运行多个任务,不一定要同时,可以交替运行。
并行 :同时运行多个任务,互不干涉。
1.1 并发编程三要素
- 原子性
原子,是指一个操作是不可中断的。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。
- 有序性
程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序,必须保证指令重排序不会影响多个线程执行的结果)
- 可见性
当多个线程访问同一个共享变量时,如果其中一个线程对这个共享变量作了修改,其他线程能知道这个修改,并获取到最新的值。
1.2 并发级别
- 阻塞
- 无饥饿
- 无障碍
- 无锁
- 无等待
饥饿,阻塞和非阻塞
阻塞:阻塞是指有其他线程占用了临界区的资源,那么当前线程必须在这个临界区中等待,导致这个线程挂起。这个线程就是阻塞的。如果一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法执行。
非阻塞:是指没有一个线程会妨碍其他线程执行,线程会一直往下执行。
饥饿:是指一个或多个线程因为某种原因无法获取所需的资源,导致一直无法执行。
例如有些线程的优先级太低,导致一直被其他高优先级的线程抢占资源执行。(竞争优先级低,无法获取线程资源)
锁
锁:通过对代码块或方法加锁来阻止线程进入,只有获取到锁的线程才能执行代码。
1.1 对象锁,重入锁,显式锁,不可重入锁,读写锁,偏向锁,可中断锁
内置锁:synchronized关键字。
对象锁:锁和对象有关,而且每个对象都会有个隐形的监视器。synchronized是一种对象锁。
显式锁:Reentranctlock类
重入锁:线程可以多次获得已经由它自己持有的锁,称之为重入锁。
synchronized关键字和Reentranctlock类都是可重入锁。
不可重入锁:当前线程获得锁之后,此线程无法再次进入同步代码,称之为不可重入锁。
读写锁:读写锁将对一个资源(比如文件)的访问分成了2个锁,一个读锁和一个写锁。
例如:ReentrantReadWriteLock,ReentrantReadWriteLock,分别为读锁与写锁。
自旋锁:自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区。
互斥锁:即两个线程获得锁是互斥的,一个线程获得了锁,其他线程在此线程释放锁之前是不能获得锁的,java提供的一个互斥锁为Reentrantlock。
可中断锁:顾名思义,就是可以相应中断的锁。
synchronized,不是可中断锁
而Reentranctlock是可中断锁(例如使用lockInterruptibly方法中断线程)。
1.2 悲观锁,乐观锁,自旋锁,互斥锁
悲观锁:对数据的一致性表示悲观。假定访问数据时,数据会被修改,所以会发生并发冲突,每次操作都会加锁。
例如独占锁,读写锁等。synchronized就是一种独占锁,也是是一种悲观锁。
乐观锁:对数据的一致性表示乐观。假定访问数据时,数据不会被修改,所以不会发生并发冲突,采用错误重试机制。每次操作申请锁失败后不会立刻挂起而是稍微等待再次尝试,如果因为发生冲突就重试,直到成功为止,以减少线程因为挂起、阻塞、唤醒(发生CPU的调度切换) 而造成的开销。
例如:偏向锁,自旋锁,CAS锁。ReentrantLock类就是一种CAS锁,也是一种乐观锁。
自旋锁:设定自旋等待的时间,等持有锁的线程释放锁后即可立即获取锁 。超时后停止自旋进入阻塞状态
偏向锁:偏向于第一个访问锁的线程 。一个线程访问触发偏向锁 ,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁
CAS锁:(比较与交换,Compare and swap) 是一种有名的无锁算法
当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试
CAS有3个操作数,内存值V,旧的预期值A,新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则等待并继续尝试。
说明
- 悲观锁会导致阻塞,性能比较低
- 乐观锁不会阻塞线程,性能比较好
- 如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次
数不得小于 3 次。
1.3 公平锁和非公平锁
非公平锁:是指线程获取锁,采用抢占机制,线程随机获取锁的。非公平锁性能更好,通常线程锁都是非公平锁。
说明
- 例如synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。
- 对于ReentrantLock和ReentrantReadWriteLock等,它默认情况下是非公平锁,
- 对于ReentrantLock和ReentrantReadWriteLock等,可以设置参数setFair(true)来使用公平锁.
公平锁:是指线程获得锁的顺序是按照线程加锁的顺序来分配的。即先来先得FIFI(先加锁的线程先执行)。
对于ReentrantLock和ReentrantReadWriteLock等,可以设置参数setFair(true)来使用公平锁.
1.5 死锁,活锁
死锁:指两个或两个以上的线程分别持有锁,并等待对方释放锁的现象。
进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。若无外力作用,死锁将永远得不到解开,比如2个线程互相持有对方的锁,互相等待对方释放锁。那么这2个线程都得不到释放锁,称之为死锁。(竞争时阻塞,相互等待,导致无法释放锁)
活锁:指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试—失败—尝试—失败的过程。处于活锁的实体是在不断的改变状态,有着最终解开锁的可能性。(竞争时谦让,一直重试,导致获取不到锁)
对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造
成死锁
1.1 Java并发编程的一些概念的更多相关文章
- java并发编程_建立概念
在学习多线程编程时,相信大家会遇到好多概念类的东西,对于这些概念的不准确理解会导致后面越学越糊涂,现将学习过程中遇到的概念整理到这篇博客上,一来记录学习点滴,二来也加深理解,如果有理解不准确的地方,希 ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- java并发编程基础概念
本次内容主要讲进程和线程.CPU核心数和线程数.CPU时间片轮转机制.上下文切换,并行和并发的基本概念以及并发编程的好处和注意事项,为java并发编程打下扎实基础. 1.什么是进程和线程 1.1 进程 ...
- 原创】Java并发编程系列2:线程概念与基础操作
[原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- 【Java并发编程实战】-----“J.U.C”:Semaphore
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...
- java并发编程系列
1.多线程的概念与使用:java笔记五:多线程的使用 2.多线程产生的问题,解决的方法, 1.引入线程池的原因:Java并发编程:线程池的使用 2.高并发情况下数据库提交:jdbc事务处理, 理解事务 ...
- java并发编程(2)--volatile(转)
转载:http://ifeve.com/volatile/ 作者:方 腾飞 花名清英,并发网(ifeve.com)创始人,畅销书<Java并发编程的艺术>作者,蚂蚁金服技术专家.目前工作于 ...
随机推荐
- open-falcon部署v0.2.1版本
环境准备 安装redis yum install redis -y systemctl start redis 安装mysql rpm -ivh http://dev.mysql.com/get/my ...
- autoit脚本-从基本的函数用法开始
适配浏览器:目前了解的有ie浏览器 MsgBox 显示可选提示超时的消息框 _ArrayDisplay _arraydisplay($aArray) ;$aArra一般为数组,方法用于展示表格展示数 ...
- npm install
npm install moduleName 命令 1. 安装模块到项目node_modules目录下.2. 不会将模块依赖写入devDependencies或dependencies 节点.3. 运 ...
- SPOJ 1812 LCS2 - Longest Common Substring II
思路 后缀自动机求多串的最长公共子串 对第一个建出后缀自动机,其他的在SAM上匹配,更新到一个节点的匹配长度最大值即可,最后对所有最大值取min得到一个节点的答案,对所有节点答案求max即可 然后注意 ...
- linux 查看命令总结
1.tail -f -n 200 cat.log 2.使用less命令 less all.2018092510.0.log 打开log文件,默认显示100行记录. 输入/CustGroupListSe ...
- MASS批量维护数据
MASS批量维护数据 https://www.fenginfo.com/2485.html 一.说明 在SAP系统的各种批量处理工具中,批量更新(Mass Maintenance) 是一种简易快捷的批 ...
- 区别samtools faid产生的.fai文件功能和bwa index 产生的四个文件的功能
samtools faidx 能够对fasta 序列建立一个后缀为.fai 的文件,根据这个.fai 文件和原始的fastsa文件, 能够快速的提取任意区域的序列 用法: samtools faidx ...
- Win10提示“因为文件共享不安全,所以你不能连接到文件共享”如何处理
在使用Windows10 1803版本系统连接CentOS6.5下搭建的Samba服务时,发现打开共享文件会遇到以下提示: 其实,该问题是Win10版本不兼容导致的.微软官方说明:https://go ...
- 2 - Binary Search & LogN Algorithm
254. Drop Eggs https://www.lintcode.com/problem/drop-eggs/description?_from=ladder&&fromId=1 ...
- [Web Service] Tutorial Basic Concepts
WSDL是网络服务描述语言,是一个包含关于web service信息(如方法名,方法参数)以及如何访问它. WSDL是UDDI的一部分. 作为web service 应用程序之间的接口,发音为wiz- ...