代码地址:https://github.com/xianzhixianzhixian/thread.git
方法lock.lockInterruptibly()、tryLock()和tryLock(long timeout,TimeUint uint)的用法和区别
1、lock.lockInterruptibly()的作用是:如果当前线程未被中断,则获取锁定(需要等待别的线程释放锁才行),如果已被中断则出现异常。但是使用lock.lock()时,当前线程被中断,不会报错。
2、lock.tryLock()和lock.tryLock(Long timeout,TimeUnit unit)的作用
lock.tryLock()的作用是:仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定,否则就不获取。就是说只会去获取未被锁定的线程。
lock.tryLock(long timeout,TimeUnit unit)的作用是:如果给定线程在等待时间内未被另一个线程保持,且当前线程未被中断,则获取该锁定,否则就不获取,相当于tryLock()加了等待时间。
方法lock.lockInterruptibly()使用示例
ServiceLockInterruptibly.java
/**
* lock.lockInterruptibly()的作用是:如果当前线程未被中断,则获取锁定(需要等待别的线程释放锁才行),如果已被中断则出现异常
* @author: xianzhixianzhixian
* @date: 2019-01-21 21:09
*/
public class ServiceLockInterruptibly {
public ReentrantLock lock = new ReentrantLock();
public void waitMethodLock(){
try {
lock.lock();
System.out.println("lock begin "+Thread.currentThread().getName());
for (int i = 0; i < Integer.MAX_VALUE / 10; i++) {
String newString = new String();
Math.random();
}
System.out.println("lock end "+Thread.currentThread().getName());
} finally {
lock.unlock();
}
}
public void waitMethodLockInterruptibly(){
try {
lock.lockInterruptibly(); //这里是非抢占式的,只有等上一个线程释放锁之后,该方法才能去获取锁
System.out.println("lock begin "+Thread.currentThread().getName());
for (int i = 0; i < Integer.MAX_VALUE / 10; i++) {
String newString = new String();
Math.random();
}
System.out.println("lock end "+Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
RunServiceLockInterruptibly.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-21 21:22
*/
public class RunServiceLockInterruptibly {
public static void main(String[] args) throws Exception {
final ServiceLockInterruptibly serviceLockInterruptibly = new ServiceLockInterruptibly();
Runnable runnable0 = new Runnable() {
@Override
public void run() {
serviceLockInterruptibly.waitMethodLock();
}
};
Runnable runnable1 = new Runnable() {
@Override
public void run() {
serviceLockInterruptibly.waitMethodLockInterruptibly();
}
};
Thread threadA = new Thread(runnable0);
threadA.setName("A");
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnable0);
threadB.setName("B");
threadB.start();
threadB.interrupt(); //此处中断threadB线程,看看结果会怎么样,不会出现异常,使用的是lock.lock()方法
Thread threadC = new Thread(runnable1);
threadC.setName("C");
threadC.start();
threadC.interrupt(); //此处中断threadC线程,看看结果会怎么样,会出现异常,使用的是lock.lockInterruptibly()方法
System.out.println("main end");
}
}
运行结果:threadA和threadB使用的是lcok.lock(),threadC使用的是lock.lockInterruptibly()方法。threadA没有被中断,从头到尾执行完成。threadB被中断,没有抛出异常。但是为什么lock end B还会被执行呢?因为仅仅靠thread.interrupt()是无法中断线程的,需要结合抛异常使用才行,"异常法终止线程运行"。threadC在执行的时候被中断,抛出异常了。
tryLock()和tryLock(long timeout,TimeUint uint)使用示例
ServiceTryLock.java
/**
* lock.tryLock()和lock.tryLock(Long timeout,TimeUnit unit)的作用
* lock.tryLock()的作用是:仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定,否则就不获取。就是说只会去获取未被锁定的线程
* lock.tryLock(long timeout,TimeUnit unit)的作用是:如果给定线程在等待时间内未被另一个线程保持,且当前线程未被中断,则获取该锁定,否则就不获取。相当于tryLock()加了等待时间
* @author: xianzhixianzhixian
* @date: 2019-01-21 21:10
*/
public class ServiceTryLock {
public ReentrantLock lock = new ReentrantLock();
public void waitMethodTryLock(){
try {
if (lock.tryLock()){
System.out.println(Thread.currentThread().getName()+"获得锁");
} else {
System.out.println(Thread.currentThread().getName()+"没有获得锁");
}
} finally {
if (lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
public void waitMethodTryLockTime(){
try {
if(lock.tryLock(3, TimeUnit.SECONDS)) {
System.out.println(Thread.currentThread().getName()+"获得锁的时间:"+System.currentTimeMillis());
} else {
System.out.println(Thread.currentThread().getName()+"没有获得锁");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()){
lock.unlock();
System.out.println(Thread.currentThread().getName()+"释放锁的时间:"+System.currentTimeMillis());
}
}
}
}
RunTryLock.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-21 21:38
*/
public class RunTryLock {
public static void main(String[] args) throws Exception {
final ServiceTryLock serviceTryLock = new ServiceTryLock();
Runnable runnable0 = new Runnable() {
@Override
public void run() {
serviceTryLock.waitMethodTryLock();
}
};
Thread threadA = new Thread(runnable0);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable0);
threadB.setName("B");
threadB.start();
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"调用waitMethodTryLockTime的时间:"+System.currentTimeMillis());
serviceTryLock.waitMethodTryLockTime();
}
};
Thread threadC = new Thread(runnable1);
threadC.setName("C");
threadC.start();
//Thread.sleep(3000);
Thread threadD = new Thread(runnable1);
threadD.setName("D");
threadD.start();
}
}
运行结果:threadA和threadB使用的是lock.tryLock(),threaC和threadD使用的是lock.tryLock(long,TimeUnit)。threadA先获得锁,而threadB在探测到threadA获得锁之后就不去获得锁了,所以显示“A获得锁,B未获得锁”。threadC和threadD都是等待3秒后再去检测锁是否被获得,threadC获得锁执行完之后3秒还未过去,此时threadD检测到threadC释放锁且等待时间未超过3秒,threadD获得锁并继续执行。