参考:http://www.dewen.net.cn/q/9077

   http://coolxing.iteye.com/blog/1236909

lock,tryLock,lockInterruptibly

分别对应无限制锁,定时锁(通过while可以作为轮询锁),可中断锁。

Lock接口的 线程请求锁的 几个方法:

lock(), 拿不到lock就不罢休,不然线程就一直block。 比较无赖的做法。
tryLock(),马上返回,拿到lock就返回true,不然返回false。 比较潇洒的做法。
带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false。比较聪明的做法。

下面的lockInterruptibly()就稍微难理解一些。

先说说线程的打扰机制,每个线程都有一个 打扰 标志。这里分两种情况,
1. 线程在sleep或wait,join, 此时如果别的进程调用此进程的 interrupt()方法,此线程会被唤醒并被要求处理InterruptedException;(thread在做IO操作时也可能有类似行为,见java thread api)
2. 此线程在运行中, 则不会收到提醒。但是 此线程的 “打扰标志”会被设置, 可以通过isInterrupted()查看并作出处理。

lockInterruptibly()和上面的第一种情况是一样的, 线程在请求lock并被阻塞时,如果被interrupt,则“此线程会被唤醒并被要求处理InterruptedException”。

E.G.  lock() & lockInterruptibly()

--lock()

 package lockInterruptibly;

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class MyService { public ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition(); public void waitMethod() {
try {
lock.lock();
// lock.lockInterruptibly();
System.out.println("lock begin " + Thread.currentThread().getName());
for (int i = 0; i < 100000000; i++) {
String newString = new String();
Math.random();
// System.out.println(i + " ");
}
System.out.println("lock end " + Thread.currentThread().getName());
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} }
 package lockInterruptibly;

 public class Run {

     public static void main(String[] args) {
try {
final MyService service = new MyService();
Runnable runnable = new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
service.waitMethod();
}
};
Thread a = new Thread(runnable);
a.setName("A");
a.start();
Thread b = new Thread(runnable);
b.setName("B");
b.start();
Thread.sleep(500);
b.interrupt();
System.out.println("main end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

正如lock()拿不到锁誓不罢休,线程b并未响应interrupt,一直在等待着锁。

--lockInterruptibly()

 package lockInterruptibly;

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class MyService { public ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition(); public void waitMethod() {
try {
// lock.lock();
lock.lockInterruptibly();
System.out.println("lock begin " + Thread.currentThread().getName());
for (int i = 0; i < 100000000; i++) {
String newString = new String();
Math.random();
// System.out.println(i + " ");
}
System.out.println("lock end " + Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} }
 package lockInterruptibly;

 public class Run {

     public static void main(String[] args) {
try {
final MyService service = new MyService();
Runnable runnable = new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
service.waitMethod();
}
};
Thread a = new Thread(runnable);
a.setName("A");
a.start();
Thread b = new Thread(runnable);
b.setName("B");
b.start();
Thread.sleep(500);
b.interrupt();
System.out.println("main end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

线程b并没有拿到锁,此时调用interrupt方法,则线程b被唤醒并被要求处理InterruptedException,即抛出了InterruptedException

当然,线程b也并不会执行了

但是当线程b拿到锁执行时才调用interrupt,这时候线程b并不会中断

tryLock() & tryLock(long, TimeUnit)

|--void lock(): 执行此方法时, 如果锁处于空闲状态, 当前线程将获取到锁. 相反, 如果锁已经被其他线程持有, 将禁用当前线程, 直到当前线程获取到锁.

|--boolean tryLock(): 如果锁可用, 则获取锁, 并立即返回true, 否则返回false. 该方法和lock()的区别在于, tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程被禁用, 当前线程仍然继续往下执行代码. 而lock()方法则是一定要获取到锁, 如果锁不可用, 就一直等待, 在未获得锁之前,当前线程并不继续向下执行. 通常采用如下的代码形式调用tryLock()方法:

|--boolean tryLock(long timeout, TimeUnit unit):如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。

通常采用如下的代码形式调用tryLock()方法:

    Lock lock = new ReentrantLock();
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}

此用法可确保如果获取了锁, 则会释放锁; 如果未获取锁, 则不会试图将其释放.

--tryLock()

 package tryLock.copy.copy;

 import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; /**
* boolean tryLock(long timeout, TimeUnit unit) 如果锁定在给定等待时间内没有被另一个线程保
* 持,且当前线程未被中断,则获取该锁定
*
* @author MicroCat
*
*/
public class MyService { public ReentrantLock lock = new ReentrantLock(); public void waitMethod() {
if (lock.tryLock()) {
try {
System.out.println(Thread.currentThread().getName() + " 获得锁");
for (int i = 0; i < 10000; i++) {
if (i % 100 == 0) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
} finally {
lock.unlock();
}
} else {
System.out.println(Thread.currentThread().getName() + " 没有获得锁");
}
} }
 package tryLock.copy.copy;

 public class Run {

     public static void main(String[] args) throws InterruptedException {
final MyService service = new MyService();
Runnable runnable = new Runnable() { @Override
public void run() {
service.waitMethod();
}
};
Thread a = new Thread(runnable);
a.setName("A");
a.start();
Thread b = new Thread(runnable);
b.setName("B");
b.start();
} }

线程b没有获得锁,a线程执行完也没有继续执行

--tryLock(long, TimeUnit)

 package tryLock.copy.copy.copy;

 import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; /**
* boolean tryLock(long timeout, TimeUnit unit) 如果锁定在给定等待时间内没有被另一个线程保
* 持,且当前线程未被中断,则获取该锁定
*
* @author MicroCat
*
*/
public class MyService { public ReentrantLock lock = new ReentrantLock(); public void waitMethod() {
try {
if (lock.tryLock(3, TimeUnit.SECONDS)) {
try {
System.out.println(Thread.currentThread().getName() + " 获得锁");
for (int i = 0; i < 10000; i++) {
if (i % 100 == 0) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
} finally {
lock.unlock();
}
} else {
System.out.println(Thread.currentThread().getName() + " 没有获得锁");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
 package tryLock.copy.copy.copy;

 public class Run {

     public static void main(String[] args) throws InterruptedException {
final MyService service = new MyService();
Runnable runnable = new Runnable() { @Override
public void run() {
service.waitMethod();
}
};
Thread a = new Thread(runnable);
a.setName("A");
a.start();
Thread b = new Thread(runnable);
b.setName("B");
b.start();
} }

在给定时间内各线程都有拿到锁,所以线程a,b都有执行

Thread--lock,lockInterruptibly,tryLock,tryLock(long timeout, TimeUnit unit)的更多相关文章

  1. C# Thread Lock 笔记

    多线程, 当使用共有变量时, 保持计算结果正确很重要: 看下面的例子: ; //private static object objlock = new object(); public static ...

  2. JAVA程序员面试笔试宝典3

    1.什么是线程?它与进程有什么区别?为什么要使用多线程 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.进程是指一段正在执行的程序. 使用多线程可以减少程序的相应时间 与进程相比,线程的创建 ...

  3. JUC - ReentrantLock 的基本用法 以及 lock()、tryLock()、lockInterruptibly()的区别

    ReentrantLock 与 synchronized对比 最近有在阅读Java并发编程实战这本书,又看到了ReentrantLock和synchronized的对比,发现自己以前对于Renntra ...

  4. ReentrantLock可重入锁lock,tryLock的区别

    void lock(); Acquires the lock. Acquires the lock if it is not held by another thread and returns im ...

  5. 阿里面试实战题2----ReentrantLock里面lock和tryLock的区别

    ReentrantLock ReentrantLock(轻量级锁)也可以叫对象锁,可重入锁,互斥锁.synchronized重量级锁,JDK前期的版本lock比synchronized更快,在JDK1 ...

  6. 多线程同步工具——Lock

    本文原创,转载请注明出处. 参考文章: <"JUC锁"03之 公平锁(一)> <"JUC锁"03之 公平锁(二)> 锁分独占锁与共享锁, ...

  7. 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

    img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...

  8. java5 Lock用法

    锁是控制多个线程对共享资源进行访问的工具.通常,锁提供了对共享资源的独占访问.一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁.不过,某些锁可能允许对共享资源并发访问,如 ReadWri ...

  9. Lock与synchronized 的区别

    多次思考过这个问题,都没有形成理论,今天有时间了,我把他总结出来,希望对大家有所帮助 1.ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候 ...

随机推荐

  1. 02 DML(DataManipulationLanguage)

    1.插入记录     基本语法 :         INSERT INTO tbl_name (col_name ,col_name1,..,col_nameN) VALUES (val1,val2, ...

  2. redisTemplate注入为空

    springboot2.*集成redis时,redis工具类中的redisTemplate注入后总是为空. 问题代码还原: 1.工具类定义成静态工具类,@Resource注入redisTemplate ...

  3. HDU - 6000 Wash(优先队列+贪心)

    题意:已知有L件衣服,M个洗衣机,N个烘干机,已知每个机器的工作时间,且每个机器只能同时处理一件衣服,问洗烘完所有衣服所需的最短时间. 分析: 1.优先队列处理出每件衣服最早的洗完时间. 2.优先队列 ...

  4. SpringBoot 系列教程之事务隔离级别知识点小结

    SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上 ...

  5. javascript 创建私有变的三个方法

    //方法一 function m() { //这是私有变量 let p = 10; //这是私有方法 function pr() { return false; } //读取或者设置 私有变量和方法 ...

  6. 用CSS编写多种常见的图形

    用CSS编写多种常见的图形 正方形与长方形 这个是最简单的,直接上代码 <!DOCTYPE html> <html> <head> <title>< ...

  7. 这26个为什么,让初学者理解Python更简单!

    为什么Python使用缩进来分组语句? 为什么简单的算术运算得到奇怪的结果? 为什么浮点计算不准确? 为什么Python字符串是不可变的? 为什么必须在方法定义和调用中显式使用“self”? 为什么不 ...

  8. 一百一十二、SAP的OO-ALV之六,复制一个工程的工具栏到另外一个工程的工具栏

    一.我们输入SE38,查看一个SAP的标准查询 二.可以看到这个程序拥有一个标准的工具栏 三.我们来到, 输入这个程序名,再点状态 四.把工具栏复制过来 五.弹出的窗口点对勾 六.系统提示已经复制 七 ...

  9. C# 读取CSV格式数据 读取为DataTable类型

    先贴代码: using System.Data;using System.Data.OleDb; static void Main(string[] args) { var strpath = Sys ...

  10. ACM-奇特的立方体

    题目描述:奇特的立方体 任意给出8个整数,将这8个整数分别放在一个立方体的八个顶点上,要求检验每个面上的四个数之和相等这个条件能否被满足. 输入 一次输入8个整数 输出 YES或者NO YES表示可能 ...