Java高并发之锁的使用以及原理浅析(4)

tryLock有两个参数,一个表示等待时长,另一个表示计时单位。在这里就是通过lock.tryLock(5,TimeUnit.SECONDS)来设置锁申请等待限时,此例就是限时等待5秒获取锁。在这里的锁请求最多为5秒,如果超过5秒未获得锁请求,则会返回fasle,如果成功获得锁就会返回true。此案例中第一个线程会持有锁长达6秒,所以另外一个线程无法在5秒内获得锁 故案例输出结果为Gets lock failed

        另外tryLock方法也可以不带参数之直接运行,在这种情况下,当前线程会尝试获得锁,如果锁并未被其他线程占用,则申请锁直接成功,立即返回true,否则当前线程不会进行等待,而是立即返回false。这种模式不会引起线程等待,因此也不会产生死锁。

下边展示了这种使用方式   

public class ReentrantLockDemo implements Runnable { //重入锁ReentrantLock public static ReentrantLock lock1 = new ReentrantLock(); public static ReentrantLock lock2 = new ReentrantLock(); int lock; public ReentrantLockDemo(int lock) { this.lock = lock; } @Override public void run() { try { if (lock == 1) { while (true) { if (lock1.tryLock()) { try { Thread.sleep(1000); } finally { lock1.unlock(); } } if (lock2.tryLock()) { try { System.out.println("thread " + Thread.currentThread().getId() + " 执行完毕"); return; } finally { lock2.unlock(); } } } } else { while (true) { if (lock2.tryLock()) { try { Thread.sleep(1000); } finally { lock2.unlock(); } } if (lock1.tryLock()) { try { System.out.println("thread " + Thread.currentThread().getId() + " 执行完毕"); return; } finally { lock1.unlock(); } } } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { ReentrantLockDemo r1 = new ReentrantLockDemo(1); ReentrantLockDemo r2 = new ReentrantLockDemo(2); Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); } }

View Code

使用了tryLock后,线程不会傻傻的等待,而是不同的尝试获取锁,因此,只要执行足够长的时间,线程总是会获得所有需要的资源。从而正常执行。下边展示了运行结果。表示两个线程运行都正常。

在大多数情况下。锁的申请都是非公平的。也就是说系统只是会从等待锁的队列里随机挑选一个,所以不能保证其公平性。但是公平锁的实现成本很高,性能也相对低下。因此如果没有特别要求,也不需要使用公平锁。

对上边ReentrantLock几个重要的方法整理如下。

lock():获得锁,如果锁已经被占用,则等待。

lockInterruptibly(): 获得锁,但优先响应中断。

tryLock():尝试获得锁,如果成功,返回true,失败返回false。该方法不等待,立即返回

tryLock(long time,TimeUnit unit),在给定时间内尝试获得锁

unlock(): 释放锁。注:ReentrantLock的锁释放一定要在finally中处理,否则可能会产生严重的后果。

Condition条件

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0e6f83f129bd3fde91f845da9f5e6d21.html