多线程学习三:Synchrounized与lock的一些点

  1. 一个对象只有一个对象锁,当一个线程获取该对象的对象锁后,其他线程就无法在获取此对象的对象锁。
  2. 当程序异常时,对于synchronized方法或者synchronized代码块,jvm会自动释放当前线程所占用的锁,所以不存在由异常引发的死锁现象
  3. Synchrounized和lock都能实现同步访问,Synchrounized属于java的内置关键字,执行完成后系统会自动使线程释放对象锁,而lock是接口,相对而言,lock更加灵活。Synchrounized修饰的代码块只有在当前线程执行完后才会释放对象所,其他线程只能等待。lock需要手动释放锁,发生异常lock也不会释放锁。
  4. lock由于不会自动释放锁,所以lock一般都在try{}catch{}块中使用,最后在finally中使用unlock()释放锁,避免异常引发死锁。在此,用lock写一个会触发死锁的程序
Lock la=new ReentrantLock();
Lock lb=new ReentrantLock();
new Thread(){
public void run(){
la.lock();//此处获取了la的对象锁
try{sleep(1000);}catch(Exception e){e.PrintstackTrance();}
lb.lock();}
}.start();//此线程持有la的对象锁,等待获取lb的对象锁。

new Thread(){
public void run(){
lb.lock();//此处获取了lb的对象锁
try{sleep(1000);}catch(Exception e){e.PrintstackTrance();}
la.lock();}
}.start();//此线程持有lb的对象锁,等待获取la的对象锁。
  1. lock中有四种方法来获取锁:lock()、tryLock()、tryLock(long time, TimeUnit unit)、lockInterruptibly()。
    lock()方法:如果锁已被其他线程获取,则进行等待。
    tryLock()方法:有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败,则返回false,也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
    tryLock(long time, TimeUnit unit)方法:与tryLock()方法是类似的,只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。
    lockInterruptibly()方法:当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态。也就使说,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。所以此方法体现Lock可以让等待锁的线程响应中断。由于lockInterruptibly()的声明中抛出了异常,所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException

你可能感兴趣的:(Java基础)