1.什么是线程安全?
在《深入理解Java虚拟机(第2版)》中,将线程安全分为了不可变、绝对线程安全、相对线程安全、线程兼容和线程对立五种:
-
不可变
- 不可变的对象一定是线程安全的
- 在Java语言里,如果共享数据是一个基本数据类型,那么只要在定义时使用final关键字修饰它就可以保证它是不可变的。 如果共享数据是一个对象,那就需要保证对象的行为不会对其状态产生任何影响。(被final修饰的字段在构造器中初始化完成前,构造器没有把“this”的引用传递出去,才能保证对象的不可变)
- 保证对象行为不影响自己状态的途径有很多种,其中最简单的就是把对象中带有状态的变量都声明为final,这样在构造函数结束之后,它就是不可变的
- Java中不可变的类型,包括String、枚举类型、java.lang.Number的部分子类等等。同为Number的子类型的原子类AtomicInteger和AtomicLong并非是不可变的,而是相对线程安全的。(AtomicInteger的源码中,value的值是通过volatile关键字进行修饰的。volatile可以保证数据的可见性,但却无法保证有序性)
-
绝对线程安全
- 绝对的线程安全完全满足Brian Goetz给出的线程安全的定义
- Brian Goetz对线程安全的定义:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的
- 绝对的线程安全完全满足Brian Goetz给出的线程安全的定义
-
相对线程安全
- 相对的线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个对象单独的操作是线程安全的,我们在调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。
- 在Java语言中,大部分的线程安全类都属于这种类型,例如Vector、HashTable、Collections的synchronizedCollection()方法包装的集合等
-
线程兼容
- 线程兼容是指对象本身并不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全地使用,我们平常说一个类不是线程安全的,绝大多数时候指的是这一种情况。
- 如ArrayList和HashMap等
-
线程对立
- 线程对立是指无论调用端是否采取了同步措施,都无法在多线程环境中并发使用的代码。
2.排序算法有哪些
3.正则表达式是什么?
详情请见正则表达式30分钟入门教程