1.线程简介
线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏
2.锁的原理
Java中每个对象都有一个内置锁。
当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。
关于锁和同步,有一下几个要点:
- 每个对象只有一个锁,提到同步时因该清楚在哪个对象上同步
- 每个对象只有一个锁,一个同步方法A获得锁后,其他线程无法获得这个实例的任何(方法A以及其他的)同步方法或同步块(同步块的锁也是该实例)
- 一个线程进入同步方法A后,不影响其他线程调用该实例的非同步方法,即非同步方法不受锁的限制
- 只能同步方法,而不能同步变量和类
- 线程睡眠不会施放任何锁
- 线程可以获得多个锁,如同个线程同步方法中调用另外一个对象的同步方法,这时就获取了两个对象的锁,需防止死锁
- 同步损害并发性,应该尽可能缩小同步范围
3.静态方法同步
- 静态同步方法,实际锁的对象是这个类的对象(XXX.class)
- 静态同步方法获取的是类对象的锁,所以一个线程获取后,其他线程只能等待获得锁后才能调用静态同步方法
- 对于静态、非静态的同步方法,获取的是不同对象的锁,可以被不同的线程同时调用
- 一个线程获得类的锁时,其他线程也不能调用该类的其他静态同步方法,会进入阻塞状态
- 静态同步方法和synchronized(类名.class)实际的效果是一样的
4.线程同步的阻塞
如果线程试图进入同步方法,而其锁已经被占用,则线程在该对象上被阻塞。
5.线程死锁
多个线程等待对方锁的情况,称为死锁。
如线程T1拥有对象O1的锁,同时又需要对象O2的锁,但O2的锁现在是属于线程T2的,而T2又需要获取O1的锁,这样就造成两个线程处于阻塞状态,都在等待对方释放需要的对象锁。