String、StringBuffer、StringBuilder
String 不可变字符序列,JDK1.0
StringBuffer 线程安全的可变字符序列,JDK1.0
StringBuilder 非线程安全的可变字符序列,JDK1.5
String是一个类,不是基本数据类型,String是值传入,非引用传入。
StringBuffer和StringBuilder两个很像,在线程安全方面,StringBuffer允许多线程进行字符操作,这是因为在StringBuffer的很多方法都被关键字synnchronized
修饰,而StringBuilder没有
StringBuilder的效率比StringBuffer稍高,如果不考虑线程安全,StringBuilder应该是首选。另外,JVM运行程序主要时间耗费是在创建对象和回收对象上。
单线程运行效率: String << StringBuffer < StringBuilder
非线程安全:StringBuilder
线程安全:StringBuffer
单线程最佳:StringBuilder
sleep和wait的区别
sleep
是线程类Thread的方法,执行此方法会导致当前线程暂停指定时间,给其他线程执行机会,但是监控状态依然保持,到时候会自动恢复。调用sleep不会释放对象锁。sleep可以在任何地方使用。sleep必须捕获异常。
wait
是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对次对象调用notify或者notifyAll方法后本线程才获得对象锁进入运行状态。使用wait的时候必须使用同步控制块(synchronized)或者同步控制方法。wait不用捕获异常
抽象类和接口
抽象类:
- 抽象类可以有构造方法
- 抽象类中可以存在普通属性,方法,静态属性和方法
- 抽象类中可以存在抽象方法
- 如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法
- 抽象类中的抽象方法,需要有子类实现,如果子类不识闲,则子类也需要定义为抽象的
接口:
- 在接口中只有方法的生命,没有方法体
- 在接口中只有常量,因为定义的变量,在编译的时候都会默认加上
public static final
- 接口中没有构造方法,永远都被public来修饰
- 接口中没有改造方法,也不能实例化接口的对象
- 接口可以实现多继承
- 接口定义的方法都需要有实现类来实现,如果实现类不能实现接口中的多有方法则实现需要定义为抽象类
Java异常
Exception异常:是程序本身可以处理的异常
Error错误:是程序无法处理的错误,这些错误表示故障发生于虚拟机自身,或者发生在虚拟机试图执行应用时,一般不需要程序处理
检查异常(编译器要求必须处置的异常):除了Error,RuntimeException及其子类以外,其他的Exception类及其子类都属于检查异常,这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句进行捕获,要么用throws子句抛出,否则编译不过
非检查异常(编译器不要求处置的异常):包括运行时异常(RuntimeException及其子类)和错误(Error)
java类的成员初始化顺序和初始化块知识
属性、方法、构造方法和自由块都是类中的成员,在创建类的对象时,类中各成员的执行顺序:
- 父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。
- 子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
- 父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。
- 执行父类的构造方法。
- 子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
- 执行子类的构造方法。
Java锁
Java中的锁作为并发共享数据,保证一致性的工具,在java平台有多种实现。
- 自旋锁 ,自旋,jvm默认是10次吧,有jvm自己控制。for去争取锁
- 阻塞锁 被阻塞的线程,不会争夺锁。
- 可重入锁 多次进入改锁的域
- 读写锁
- 互斥锁 锁本身就是互斥的
- 悲观锁 不相信,这里会是安全的,必须全部上锁
- 乐观锁 相信,这里是安全的。
- 公平锁 有优先级的锁
- 非公平锁 无优先级的锁
- 偏向锁 无竞争不锁,有竞争挂起,转为轻量锁
- 对象锁 锁住对象
- 线程锁
- 锁粗化 多锁变成一个,自己处理
- 轻量级锁 CAS 实现
- 锁消除 偏向锁就是锁消除的一种
- 锁膨胀 jvm实现,锁粗化
- 信号量 使用阻塞锁 实现的一种策略
- 排它锁:X锁,若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。
产生死锁的主要原因
- 因为系统资源不足
- 进程运行推进的顺序不合适
- 资源分配不当
如果系统资源充足,进程的资源请求都能够得到满足,出现死锁的可能性很低,否则就会因为争夺优先的资源而陷入死锁。进程运行推进顺序与速度不同,也可能产生死锁
产生死锁的4个必要条件
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
- 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾详解的循环等待资源关系
上面是产生死锁的4个条件,只要系统发生死锁,这些条件必然成立,只要上述条件之一不满足,就不会产生死锁
死锁的解除与预防
理解了产生死锁的原因和产生死锁的四个必要条件,就可以最大可能的避免,预防和接触死锁。
在系统设计,进程调度等方面注意如何不让产生死锁的4个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的的分配要给予合理的规划。