java多线程-Lock

大纲:

  1. Lock接口
  2. synchronized&Lock异同

一、Lock

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}
  1. lock()获取锁。
  2. lockInterruptibly()可打断的获取锁方法,仅可打断等待锁的线程。
  3. tryLock()获取锁并返回结果,得到锁的线程返回true,没有拿到锁的线程不再等待并返回false。
  4. tryLock(time)带参数函数,可以传入一个时间,在这个时间内获得锁的线程返回true,没有获得锁返回false,且在这个时间内等在锁的线程可以被打断。
  5. unlock()释放锁。
  6. newCondition 创建一个场景(见下章)。

注意:打断正在获取锁的线程时,lockInterruptibly,tryLock都会抛出InterruptedException。此时不能用try,catch,finally结构将InterruptedException捕获,执行finally中的unlock操作,因为该线程并没有获得锁,unlock操作也会报错。因此最好将这个InterruptedException向上抛出,由上级try,catch。

例:

ReentrantLock为Lock接口唯一实现类
public class Met {
    Lock lock = new ReentrantLock();

    public void action(Thread thread) throws InterruptedException {
        if(lock.tryLock(2, TimeUnit.SECONDS)){
            try {
                System.out.println(thread.getName()+"lock");
                for(int i =0;i<20000;i++){
                    System.out.println(thread.getName()+":"+i);
                }
            } finally {
                System.out.println(Thread.currentThread().getName()+"run finally");
                lock.unlock();
                System.out.println(thread.getName()+"unlock");
            }
        }
    }
}
public class MyRunnable implements Runnable {
    Met met;
    MyRunnable(Met met){
        this.met = met;
    }
    @Override
    public void run() {
        try {
            met.action(Thread.currentThread());
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName()+"interrupted");
        }
    }
}
class TestLock {
    public static void main(String[] args) {
        Met met = new Met();
        MyRunnable myRunnable0 = new MyRunnable(met);
        MyRunnable myRunnable1 = new MyRunnable(met);
        Thread thread0 = new Thread(myRunnable0);
        Thread thread1 = new Thread(myRunnable1);
        thread0.start();
        thread1.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread1.interrupt();
    }
}

本例执行后,线程1被打断,由于是trylock(2分钟),因此抛出中断异常,上级catch后打出日志

Thread-0:2865
Thread-0:2866
Thread-1被中断
Thread-0:2867
Thread-0:2868
Thread-0:2869

二、synchronized&Lock异同

  1. synchronized代码块内发生异常,锁会自动释放、lock需要在finally中手动释放。
  2. synchronized无法锁的获取情况。
  3. synchronized无法设置超时。
  4. synchronized无法中断等待获取锁的线程。
  5. synchronized无法设置是否公平锁,lock和synchronized默认是非公平锁。
  6. 大并发,lock性能优于synchronized。
  7. lock和synchronized都是排他、重入锁。

猜你喜欢

转载自www.cnblogs.com/liuboyuan/p/10281505.html