Java并发性和多线程
转载自http://ifeve.com/java-concurrency-thread-directory/
简要总结
并发性和多线程的区别和联系
多线程是并发的一种实现。并发还可以使用分布式/多进程实现。
并发模型:并行工作者、流水线工作者/事件驱动模型
Java多线程两/四种创建方式
继承Thread,(匿名/不匿名)子类
实现Runnable接口,(匿名/不匿名)类
竞态条件(race condition)和临界区()
当多个线程同时访问某一代码区,对共享的资源做出了更改,若运行结果与多个线程的访问顺序有关,则称形成了竞态条件,与之相关的这一代码区域称为临界区。
多个线程同时更新共享资源时会形成竞态条件。
线程安全与共享资源
多线程中某些资源是被共享的。多个线程同时更新共享资源时会形成竞态条件。允许被多个线程同时执行的代码称作线程安全的代码。线程安全的代码不包含竞态条件。要明白哪些资源是线程安全的(方便使用的)。
- 局部基本变量(线程安全)
- 局部对象引用(方法中对象的引用没有逃逸,或者没有被其他线程引用,就是安全的)
- 对象成员(不安全)
- 使用不可变对象(没有setter的类实例,线程安全)
- ThreadLocal(创建的变量只被同一个线程读写,在多个线程中有不同的副本,仅初始值相同。线程安全)
参考java内存模型可以明白它们为什么是线程安全或不安全的。
线程控制逃逸规则:如果一个资源的打开、使用、销毁都是在一个线程中完成的。且不会脱离该线程的控制,该资源的使用就是线程安全的。
资源:包括对象、数组、文件、数据库连接、套接字等。
即使对象本身是线程安全的,但对象使用的资源可能不安全,如包含了数据库多步操作。
Java同步块
多线程开发时,要使用线程安全的资源(不存在竞争)。对于线程不安全的资源/存在竞争的的情况,使用同步块来避免竞争。
同步块可以保证一次只有一个线程进入临界区(加同步块的代码区),其他线程被阻塞(不恰当的编程可能导致一直阻塞,也就是死锁)。Java中的同步块使用synchronized关键字来标记。同步都加在类对象上。
实例方法同步
静态方法同步
实例方法中的同步块
静态方法中的同步块
线程通信
在保证线程安全的基础上,线程间应当可以通信。
使用共享对象通信:共享对象中加锁(加同步块)防止竞争,在不同线程中使用此对象。
简单实现:共享对象中加锁(加同步块)防止竞争,线程1发送消息,线程2通过轮询等待(忙等待,缺点是cpu资源消耗大)
Java内建通信机制:共享对象加锁(使用同步块),在同步块中使用wait()\notify()\notifyAll()函数。
解决信号丢失(notify在wait之前):Java内建通信机制+判断共享对象成员变量(保存notify状态)
解决假唤醒(特殊情况下wait返回向后执行):Java内建通信机制+循环判断共享对象成员变量(保存notify状态)
注意不要使用字符串常量作为共享对象(JVM中相同的字符串常量指向了同一个地址),还有全局对象。
死锁
同步块解决线程不安全代码的竞争问题,但同步块可能有死锁的隐患。当一个线程进入同步块(代码临界区),其他线程被阻塞(不恰当的编程可能导致一直阻塞,也就是死锁)。
例子:如果线程1锁住了A,然后尝试对B进行加锁,同时线程2已经锁住了B,接着尝试对A进行加锁,这时死锁就发生了。线程1永远得不到B,线程2也永远得不到A,并且它们永远也不会知道发生了这样的事情。为了得到彼此的对象(A和B),它们将永远阻塞下去。
2+线程的死锁
数据库更新记录的死锁
死锁避免
加锁顺序
加锁时限
死锁检测
mark vert.x
未学习:java中的锁,信号量,线程池等
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- SAP CDS view单元测试框架中的访问者(Visitor)设计模式使用介绍
- Cheerio爬虫-解决网易GBK字符的乱码问题
- HashMap源码学习
- HashTable源码学习
- HashSet源码学习
- ConcurrentHashMap源码学习
- 线程池参数详解
- Thread源码解析
- ThreadPoolExecutor源码学习
- 实习第三周
- ABAP和JavaScript的懒加载,单例和桥接模式的实现和比较
- ExecutorCompletionService源码学习
- Erlang和RabbitMQ的windows环境配置
- ScheduledThreadPoolExecutor源码学习
- Github创建您的私服