synchronized关键字
- 为了解决多线程的线程安全问题,java引入了synchronized关键字来实现线程之间的同步
- 同步代码块:(同步代码块的监视器锁对象可以是任意对象,一般写需要被同步的对象)
synchronized(obj)
{
//需要同步的代码块
}
obj代表的就是同步监视器对象,就是锁,线程开始执行同步代码块之前必须先获得监视器锁。
- 同步方法(同步方法的监视器锁是this,也就是调用该方法的对象,同步方法不需要显示的指定监视器锁对象)
public void synchronized method(){
}
同步锁(Lock接口)
- jdk1,5后java提供了更加强大的同步机制,通过显示定义同步锁对象来实现同步。
- Lock是控制多个线程对共享资源进行访问的工具,Lock和ReadWriteLock是java1.5提供的两个根接口
- ReentrantLock(可重入锁)是Lock的实现类,是常用的线程安全控制的锁
class A{
private final Lock lock=new ReentrantLock();//创建锁对象
public void method(){
lock.lock();//枷锁
try{
//需要同步的代码
}finally{
lock.unlock();//释放锁
}
}
}
- 通过显示的调用lock和unlock方法来进行同步操作,通常将释放锁放在finally块中保证锁能够被释放。
synchronized和Lock的区别:
- synchronized是隐式的加锁和释放锁
synchronized释放锁的时机:
1.同步代码块,同步方法执行结束后,当前线程会释放锁
2.同步代码块,同步方法中遇到break,return终止了代码块,方法的执行,线程释放锁
3.同步块,同步方法中有未处理的Error和Exception,导致同步块和方法异常结束时,会释放锁
4.当前线程执行同步块,同步方法时,程序执行了同步监视器对象的wait()方法,线程暂停,并释放锁
以下情况不会释放锁:
1.调用sleep()方法,yield()方法等
2.其它线程调用当前线程的suspend()方法挂起该线程时(程序应避免调用suspend()和resume()方法来控制线程) - Lock是通过lock和unlock方法显示的加锁和释放锁