1)概念:什么是线程安全:代码在多线程执行下和在单线程执行下获得的结果是一样的,就认为是线程安全的。
2)线程安全级别:
不可变对象:如String、Integer、Float、Double等包装类都是final类型的类,任何一个线程都改变不了他们的值,除非新创建一个,这样的对象不用使用任何同步手段就可以直接在多线程环境下使用。不可变对象保证了内存的可见性,对不可变对象的读取不需要额外的同步手段,提升了代码执行效率。
相对线程安全:也即常见的线程安全,如Vector,每一个add、remove、方法都是原子操作,不会被打断,但是也仅限于此,如果一个线程正在访问,另外一个线程同时在add,99%的情况会报错ConcurrentModifiedException这就是所谓的fail-fast
绝对线程安全:不管外部环境如何,调用者都不用额外的同步措施。要做到这一点需要付出很多额外的代价,java中标注线程安全的类绝大部分不是绝对线程安全的,绝对线程安全的类,也有,如CopeOnWriteArrayList、CopyOnWriteArraySet
线程非安全:HashMap、ArrayList、LinkedList等都不是线程安全的。
3)sleep和wait的区别:
sleep和wait都是可以用来放弃CPU一定的使用时间,不同点在于,sleep休眠的时候不会放弃对该线程的监视,wait在休眠的时候会放弃对象的监视器。
4)join
在很多情况下,主线程生成并启动了子线程,如果子线程里面需要大量的耗时计算,主线程往往在子线程结束之前结束,但是如果主线程依赖于子线程的结果就可能出现异常。这个时候就需要用到join方法了。join的作用是等待该线程终止,也即主线程等待子线程终止,也就是子线程在join方法后面的代码,只有等到子线程结束了才能执行主线程。