Java 并发编程之线程安全性
2014-08-18 11:09
239 查看
原子性
假定有两个操作A和B,如果从执行A的线程来看,当另一个线程执行B时,要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说就是原子的。换句话说是执行独立性。竞态条件
基于一种可能失效的观察结果来做出判断或者执行某个计算。串行访问
多个线程依次以独占的方式访问对象。锁的作用就是这个比如我们在设计模式中经常用到的单例模式。其实在并发编程里是不安全的。
public class Init { private Init instance = null; public Init getInstance() { if (instance == null) instance = new Init(); return instance; } }
在单线程程序中是一个不错的设计模式,可是在多线程中可能遇到 这样的问题,当A和B两个线程同时调用getInstance()方法时,对instance来说。得到的结果都是Null,那么getInstance()方法将会被执行两次,如果这个方法的实例化过程在两个线程中是一样的,那么只影响效率而已,如果在两次实例化中,进行的过程并不一样,那么可能会影响到后面的程序执行了。
在java.util.concurrent.atomic包中包含了一些原子变量类。用于实现数值和对象引用 上的原子状态转换
用这些变量类可以保证操作都是原子的。
另外在多线程中,所引用的变量都需要声明为final类型以保证引用不会被改变。这点在eclipse里会自动提示你。否则会报错。
java提供了内置锁用于并发编程。非常方便
synchronized(lock){ //访问或修改由锁保护的共享状态 }
前面有一篇专门讲过java线程与锁
点击打开链接
重入
内置锁是可以重入的,重入的一种实现方法是为每个锁加一个计数器,像jvm中的垃圾回收机制一样,当同一个线程再次调用这个方法时,计数器加1,当计数器为0时认为这个锁没有被持有,。看下面的代码public class Init { public synchronized void dosomething() { } } class init extends Init { public synchronized void dosomething() { System.out.println("dosomething"); super.dosomething(); } }
子类和父类都使用了synchronized方法 。子类改写并调用了父类的synchronized方法。重入就避免上面代码无限循环的问题。如当子类调用父类的dosomething方法时,子类已经持有了锁,而父类无法获得。那么将永远等待下去 。
参考资料:《java并发编程实战》
相关文章推荐
- [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
- java并发编程实践之线程安全性
- JAVA并发编程之线程安全性
- Java并发编程之线程安全性
- 【Java并发编程实践】线程安全性、对象的共享和对象的组合
- [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
- java 并发编程实战 之 线程安全性
- Java并发编程学习——《Java Concurrency in Practice》学习笔记 2.线程安全性
- Java并发编程实践笔记 第一部分 基础知识 第二章 线程安全性
- java 并发编程第二节 线程安全性
- java并发编程实战之线程安全性
- Java并发编程实践---第二章:线程安全性
- java并发编程-Executor框架1
- 探索并发编程(六)------Java多线程性能优化
- Java并发编程--三个线程顺序打印ABC
- Java 多线程与并发编程专题(转)
- Java并发编程--fork-join framework(a parallelizable algorithm)
- java并发编程实践 笔记(1)
- Java 并发核心编程
- Java编程思想——并发(1)