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并发编程的艺术>作者,蚂蚁金服技术专家.目前工作于 ...
随机推荐
- VueScroller 使用
下载插件 npm install vue-scroller -D 引入插件: import Vue from 'vue'import VueScroller from 'vue-scroller' ...
- jsp+postgresql学习笔记(1)用户登录与注册
前期准备: tomcat的安装与配置(略) jdk的安装与配置(略) eclipse软件安装与配置(略) webstrom软件或IDEA的安装与配置(大概用了IDEA就不需要eclipse了,但是怎么 ...
- 【新特性】JDK11
随着JDK11正式发布,带来了许多新的特性.本文主要介绍JDK11的部分新特性和新的API. 一.Local Var 在Lambda表达式中,可以使用var关键字来标识变量,变量类型由编译器自行推断. ...
- ArrayList迭代器源码分析
集合的遍历 Java集合框架中容器有很多种类,如下图中: 对于有索引的List集合可以通过for循环遍历集合: List<String> list = new ArrayList<& ...
- 【Python】函数总结
以下为自学笔记内容,仅供参考. 转发请保留原文链接https://www.cnblogs.com/it-dennis/p/10516688.html python中的函数 最近看了python中关于函 ...
- IOS Xcode编译项目-报错“ld: library not found for -XX”
一般是因为导入新项目的时候报错的.原因是引入的依赖库的问题.重新执行pod install应该可以解决.不过,有时候如果重新执行pod install无法执行,可以采用以下方法: 在终端中cd到项目所 ...
- 【GIT】【命令行】
1) 进入某没有做git的目录: git init ->username@DESKTOP-765V31O MINGW64 ~/PycharmProjects/user_data (master) ...
- hadoop搭建笔记(一)
环境:mac/linux hadoop版本:3.1.1 安装特性:非HA 准备: 1. jdk8以上 2. ssh 3. 下载hadoop安装包 配置文件,这里都只有简易配置: 1. core-sit ...
- LeetCode03 最长无重复子串
题目 给定一个字符串,找出不含有重复字符的最长子串的长度. 解答 刚开始以为只是一遍遍历后来的字符和前面一样便开始算新子串,给的案例都过了,但是卡在了"dvdf" 后来经过重重试验 ...
- git commit -m 提交的内容换行
网上说只需要通过单引号来换行,一直没理解,后面终于试出来了.总结一句话就是. . 先输入第一个引号,按Enter即可换行,完成后再补齐后面的引号 // 步骤一: 输入第一行 git commit -m ...