本文共 1527 字,大约阅读时间需要 5 分钟。
活跃性问题: 比如单线程中出现的无限循环
性能问题:和活跃性问题相对, 活跃性问题意味着正确的事情一定会发生,但是不够好,我们希望正确的事情尽快发生
线程安全性: 一个类,被多个线程同时调用,且多个线程不需要额外的同步机制,就能保证这个类的方法被正确执行,那么这个类就是安全的
原子性:count++就不是原子操作,它分为读取修改写入三个操作,boolean的读写是原子操作
竞态条件: 最常见的就是先检查后执行.意味着程序的正确性依赖于多线程执行时序的正确性
不变性条件:即一组操作,通过加锁的方式,保证这组操作以原子操作的方式执行
复合操作:访问一个状态的所有操作,要以原子性的方式访问, 即这组操作只能同时在同一个线程中执行,其他线程必须等待 重入: 同一个线程可以重入他获得的所有锁 重排序: 编译器和运行时和处理器可能对操作进行重排序(处于性能方面的考虑), 比如构造器中初始化对象中的变量和返回这个对象引用,这两个操作,可能出现构造器没有完全初始化,引用就被返回,.这种现象被称为不安全的发布可见性问题:当前线程对共享变量的修改对其他线程不可见,内置锁可以保证同步代码块中的变量的更新对其他所有线程可见
发布:将一个对象暴露到多线程环境中 逸出:一个本不该被暴露到多线程环境的对象被错误的暴露到多线程环境中构造器中的this指针逸出:不论是逸出到多线程还是当前线程,都会出错,可能读取到的是未完全初始化的变量值,比如int i,首先默认设置为0,然后在构造器中初始化为100,如果构造器中this指针逸出,那this可能读取到不正确的0值
安全地构造对象: 保证this指针不会再构造器中逸出即可,可以使用静态方法进行初始化
线程封闭: 栈封闭:使用局部变量,局部变量一定是当前线程私有的, threadLocal 类:ThreadLocal中的数据被封闭在当前线程中
对象的不变性: 1,对象被正确创建(正确创建指的是构造过程this指针没有逸出)
2,对象创建之后,状态不允许被修改
3,所有的于都是final类型的(这个不需要,只要保证实际不可修改即可,比如吧对象放到ConccurencyMap中,外围类只提供isContain()方法). 同时不可变对象一定是线程安全的
申请了内存用完了不释放,比如一共有 1024M 的内存,分配了 521M 的内存一直不回收,那么可以用的内存只有 521M 了,仿佛泄露掉了一部分
申请内存时,没有足够的内存可以使用;
内存泄漏和内存溢出的关系:内存泄露的增多,最终会导致内存溢出。
循环过多或死循环,产生大量对象;
静态集合类引起内存泄漏,因为静态集合的生命周期和 JVM 一致,所以静态集合引用的对象不能被释放;下面这个例子中,list 是静态的,只要 JVM 不停,那么 obj 也一直不会释放。
3.单例模式,和静态集合导致内存泄露的原因类似,因为单例的静态特性,它的生命周期和 JVM 的生命周期一样长,所以如果单例对象如果持有外部对象的引用,那么这个外部对象也不会被回收,那么就会造成内存泄漏。
4.数据连接、IO、Socket连接等等,它们必须显示释放(用代码 close 掉),否则不会被 GC 回收。
5.内部类的对象被长期持有,那么内部类对象所属的外部类对象也不会被回收。
6.Hash 值发生改变,比如下面中的这个类,它的 hashCode 会随着变量 x 的变化而变化:
转载地址:http://mhxzb.baihongyu.com/