网站首页 > java教程 正文
序文:
如果你没有时间阅读这本,那你就来对地方了。小编会将每一章刨去废话,取其精华。分享给大家。如果觉得可以请不要忘了关注小编。我会定期跟新java 中的经典书籍。
正文:
第二章:线程安全性 (这一章多为概念记住就好,没有详细介绍)
- 一个对象是否需要考虑线程安全,取决于他是否被多个线程访问。
- 要使得对象线程安全,需要采用同步机制来控制对对象可变状态的访问。
- 对象的状态:除去对象的方法。其余的变量,对其他的对象的引用等。
- 可变状态:非final修饰的属性
- java 中的同步的实现方式(先罗列):
- synchronized,它提供了一种独占的加锁方式,
- volatile
- 显示锁
- 原子变量:AtomicInteger AtomicLong ..(java 中多以Atomic开头的类)
- 如果当多个线程访问同一个可变状态(可以简单理解为全局变量)时,有三种方法来实现线程安全:
- 不在线程之间共享该状态变量
- 将状态变量修改为不可变的变量(final)
- 在访问状态变量时候使用同步(最符合实际)
- 程序状态的封装性越好,就越容易实现程序的线程安全。(就是不该共享的不共享)
- 何为线程安全性:当多个线程访问某个类时,这个类始终能表现出正确的行为,那么就称这个类是线程安全的。
- 在使用这个类的的时候不需要使用额外的同步代码(类的内部使用同步已经确保类的线程安全,比如 原子变量类)
- 无状态的对象一定是线程安全的。
- 无状态对象:不包含任何域,也不包括对其他类中域的引用。(即只有方法,没有全局的属性变量)
- 无状态多线程之间没有共享的变量,所以各自做各自的事情互不干扰
- 复合操作
- ++ 操作为例:可以分为三步 读取-修改-写入 一旦是多个操作组成,线程在执行一个操作完成后就可能,被切换到执行其他的事情。
- 这样就可能产生静--竞态条件:由于不恰当的执行时序而出现不正确的结果
- 产生场景:有先后顺序的执行代码中,如果满足某种条件就执行(先检测后执行)
- 如何避免竞太条件问题:
- 必须在某个线程修改该变量时,通过某种方式防止其他线程使用这个变量(原子方式执行)
- 在无状态类中添加一个线程安全对象的属性,那么这个类任然是线程安全的。
- 比如添加一个原子变量(AtomicInteger )这个类任然是线程安全的。(只能是一个 ,如果添加多个就不一定了)
- 原子变量只适合少量(一个是最佳),如果多个就要考虑使用加锁机制了(且最好不要混用)。
- 内置锁:同步代码块(使用内置锁机制来支持原子性)
- 同步代码块包括两个部分
- 锁的对象引用
- 这个锁保护的代码块
- 用关键此 synchronized 来修饰
- 直接用在方法定义上 ,那么这这个方法体整个都是原子操作,锁对象是调用这个方法的对象(如果用在静态方法上,锁对象是这个类的Class对象)。
- 每个java 对象都可以用做一个实现同步的锁,这些锁被称为 内置锁或监视器锁。
- 线程进入同步代码块时获得锁对象,保存在jvm中
- 推出时(正常和异常退出都是)释放锁
- 获得锁的唯一途径就是进入同步代码块,或者同步方法。
- 锁的重入
- 何为重入:获取锁的线程,再一次获取同一个锁,
- 如何实现的:
- 当一个线程获取一个锁的时候,jvm会记录下锁的持有线程,并且将创建一个计数器,计数器初始是0,表示没有任何线程持有该锁。如果是1有线程进入到同步代码块中;如果是2说明这个线程重入了。
- 即进入+1,退出-1
- 只有计数器为0的时候才说明这个锁完全释放了。
- 例子:
- 父类中有一个方法是同步方法
- 子类是一个同步方法调用了父类的同步方法。
- 注意:
- 扩展一下,super 和this 都是同一个子类对象。(所以获取的锁都是子类对象)
- 同步可以保证线程安全但是不能滥用:
- 一个方法使用同步那么这个方法就不可以被并发执行,导致多个线程在等待cpu处于空闲
- 何时使用同步:
- 共享变量的访问和写入(不要错误的理解只有写入)
- 一个共享的变量所在的所有的地方都需要同步,并且用的是同一个锁。
- 如果合理的使用同步(总结)
- 同步代码块尽可能小
- 不需要的同步的代码尽量分离出来不要放在代码块中
- 只有一个共享变量的时候使用原子变量
- 不要混用同步代码块和原子变量
- 执行时间长的操作(网络I/O ,控制台I/O)不要持有锁
猜你喜欢
- 2024-10-25 Java 多线程并发编程面试笔录一览
- 2024-10-25 我和面试官的博弈:Java 并发编程篇
- 2024-10-25 清华大牛出版的java并发编程从入门到精通,不要让它继续蒙灰了
- 2024-10-25 JAVA多线程并发编程-避坑指南(java多线程并发调用接口)
- 2024-10-25 阿里大神再秀神作!凭借“347页核心笔记”带你玩转并发编程
- 2024-10-25 Java并发编程实战:深入理解线程池
- 2024-10-25 Java并发编程实践简单案例-顾客排队
- 2024-10-25 2020程序员都在看的PDF:《Java 多线程编程实战指南(核心篇)》
- 2024-10-25 Java并发编程(一)-Java线程状态及其转换(理论+实战)
- 2024-10-25 12W字!阿里P8架构师手写“Java并发手册”带你横扫全网
你 发表评论:
欢迎- 最近发表
-
- Java内存溢出紧急处理:10个必知的Linux命令快速定位OOM
- 面试常问的 25+ 个 Linux 命令(linux面试命令大全)
- Java堆外内存溢出紧急处理实战:Linux命令定位与Spring Boot解决
- java开发常用的Linux命令,高频的没你想象的多
- Java 应用 CPU 飙升?8 个 Linux 命令组合拳快速锁定异常线程
- Java 开发者线上问题排查常用的 15 个 Linux 命令
- Java程序员必备的Linux命令:让你的工作效率翻倍
- Java程序员必备的Linux命令全解析
- [超全整理] Java 程序员必备的 100 条 Linux 命令大全
- SAP ABAP资源导航(sap aatp)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)