概念篇
1: 为什么需要多线程
在程序处理多任务时,在单线程下,如果其中一个任务被阻塞了(比如IO操作),那么所有的任务都无法前进,知道被阻塞的任务进行前进,将浪费很大的系统资源。
那么解决方案就是某一项任务暂时不适用资源时,就将资源释放出来,供其他的任务适用,这种方式就是多线程。
2:多线程有什么问题
多线程能极大程度上利用空闲的资源。如果多个线程之间共享了某一份数据,如果不进行同步,共享的数据将被破坏。
因此多线程编程的难点就是如何保证对共享数据的同步。这也是多线程中唯一的一个问题,该问题可引发其他许许多多的后续问题和技术,比如:死锁、非阻塞算法等等。
3:Java的内存模型
平台的存储模型:
每个线程、寄存器都有自己的内存空间,因此对于同一存储位置(比如:没有同步的变量),允许不同的线程看到
不同的值。
重排序:
在一个没有进行同步的程序中,线程之间的执行先后顺序是没有保障的。那么线程将变量的值从变量的存储位置拷贝到线程的内存的时机也是各不相同的。
Java的内存模型:
happens-before : 如果动作B要看到动作A执行后的结果,那么称为A happends-before B,即A发生在B之前。
如果没有对两个动作定义了happens-before的关系,那么JVM就可以对他们进行任意的重排序。
happens-before:常见的有:
程序次序:单线程的代码是按代码的前后顺序执行
访问同步的变量
volatile写操作happens-before在其完成后的所有读操作。
4:volatile变量
volatile关键字指的是,线程每次读取volatile的变量的值,都是重新从变动的存储位置读取,因此能保证是最新写入的值。
和锁的区别在于:加锁(这里以排它锁举例)读取时,别的线程不能对这个变量进行操作;而volatile则没有这层限制。
因此volatile变量不能用于类似自增的操作,因此自增的操作是:取当前值A,加1,将A+1的值付给变量。由于volatile只保证取值是最新写入的值,那么就可能发生取完最新值A后,别的线程就可能对该变量写了很多次值,因此volatile变量不适于自增操作。
volatile只能用于保证可见性(读的都是最新写入的数据),不能保证原子性。原子性的操作就需要锁或者CAS.
5:发布对象
发布对象:如果该对象能够被别的代码(别的线程)访问到,那它就是被发布出去了。
发布出去的对象需要考虑:别人是否会该其对象的内部结构。
不好的实践:
返回一个数组
返回匿名内部类,隐藏了对外部类的引用,同时也是一种很隐秘的内存泄露方式。
6:不需要同步的数据
不需要同步的数据:在多线程,不加锁的情况下不会被破坏的数据。
1:不可变对象:比如String,Date,int等。
注意final对象只表示引用所指向的对象地址不会改变,不表示对象的内部状态不变。final对象不一定是不可变对象。
2:只在单线程中使用的变量:
方法中不返回的局部变量;存放于ThreadLocal中的变量;
7:线程安全:
线程安全:类所提供的每一个方法在多线程情况下是不会损坏数据时,则表示线程是安全的。
注意:使用线程安全的方法,不一定就是安全的。组合使用两个线程安全的方法时,在两个线程安全的方法之间别的线程可能破坏数据。
if(vector.contains()){
vector.add().
}
8:死锁与open call:
如果线程1获得锁A,正在申请锁B,而同时线程2获得了锁B,正在申请锁A。这将发生死锁。
open call : 当一个方法中不获得锁时,称为open call。
为什么需要open call:
两个原因:
1:因为外部一个方法可能需要多个内部的方法完成,如果多个内部的方法都持有锁时,性能较低。
2:为了更好的避免死锁,如果你加了锁而调用方的另一些方法也加了同样的锁,那么就容易造成死锁。
因此一个可采取的方法是:
1:尽可能的使用open call
2:一定要加锁时,不同的类里的方法使用不同的锁机制、锁标识,同一类中要按顺序加锁。
分享到:
相关推荐
本笔记将深入探讨《Java Concurrency In Practice》这本书中的核心概念,结合Guava库的实际使用案例,帮助读者理解并掌握Java并发编程的精髓。 首先,我们来了解Java并发的基础知识。Java提供了丰富的并发工具类,...
《Java Concurrency in Practice》中文版笔记
Addison.Wesley.Java.Concurrency.in.Practice.May.2006.chm Agile Java 测试驱动开发的编程技术.pdf Java 8 默认方法和多继承.docx Java NIO通信框架在电信领域的实践.docx java.png javaconcurrencyinpractice.pdf...
Concurrency in Practice 读书笔记和示例代码 包括 线程基础/同步sync/并发concurrent/容器/线程池 示例代码 JUC容器的源码解析 Synchronized 同步容器 Concurrent 并发容器: Map/List/Queue 阻塞队列 JUC锁: ...
并发编程实战》阅读笔记 有关 Java 并发编程~ 别急别急,在重写它啦~,会补充一些新的内容进去,预计 2020/02 完成。 Content Java 并发编程基础 保证线程安全的两个角度 构造安全的并发应用程序 Java 并发高级主题 ...
书籍如《Effective Java》、《Java Concurrency in Practice》和《Head First Java》等,都是学习Java高级编程的经典之作。在线资源如Oracle的Java Tutorials和Stack Overflow上的问答,为解决实际问题提供了大量...
Addison.Wesley.Java.Concurrency.in.Practice.May.2006.chm Agile Java 测试驱动开发的编程技术.pdf Java 8 默认方法和多继承.docx Java NIO通信框架在电信领域的实践.docx java.png javaconcurrencyinpractice.pdf...
【Java并发编程实战】的阅读笔记-英文版:Java Concurrency in Practice官网源代码地址: : 1.主要是对源代码作一些补充并能实际运行一下(以junit的方式)2.添加了java8newfeatures,主要是写了几个java8的新...
Java Concurrency in Practice 对象的共享 对象的组合 基础构建模块 JavaGC监控与优化 垃圾回收机制 垃圾回收机制的监控 优化垃圾回收机制 Apache的MaxClients参数详解及其在Tomcat执行FullGC时的影响 JavaEE 浅析...
- **书籍**:《Effective Java》、《Java Concurrency in Practice》、《Clean Code: A Handbook of Agile Software Craftsmanship》等经典书籍深入讲解Java编程技巧和最佳实践。 - **社区与论坛**:Stack Overflow...