一、线程优先级
- 线程优先级用数字表示,范围0-10,默认值是5
- 优先级越高,获得CPU调度的概率越大
- 使用getPriority()方法获取线程,setPriority()方法设置线程
- 先设置优先级,再启动线程
二、守护线程
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
三、线程同步
每个线程都有自己的工作内存,并且每个线程在自己的工作内存交互,内存控制不当会造成数据不一致。
同步方法,同步块。
synchronized方法和synchronized块最难的一个点是锁的对象。
synchronized方法默认锁的是这个对象这个类本身,synchronized块可以锁任何对象。
锁的对象就是变化的量,也就是需要增删改的对象。
四、死锁
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。
五、Lock锁
synchronized与Lock的对比
- Lock是显示锁(手动开启和关闭锁,别忘记关闭锁)synchronize是隐式锁,出了作用域自动释放
- Lock只有代码块锁,synchronize有代码块锁和方法锁
- 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)
- 优先使用顺序:
- Lock>同步代码块(已经进入了方法体,分配了相应资源)>同步方法(在方法体之外)
Lock(锁)
class A{
//可重入锁
private final ReentrantLock lock = new ReentrantLock();
public void m(){
lock.lock();
try {
//保证线程安全的代码;
}
finally {
lock.unlock();
//如果同步代码有异常,要将unlock()写入finally语句块
}
}
}