Java多线程中Lock的使用
Jdk1.5以后,在java.util.concurrent.locks包下,有一组实现线程同步的接口和类,说到线程的同步,可能大家都会想到synchronized关键字,
这是java内置的关键字,用来处理线程同步的,但这个关键字有很多的缺陷,使用起来也不是很方便和直观,所以就出现了Lock,下面,我们
就来对比着讲解Lock。
通常我们在使用synchronized关键字的时候会遇到下面这些问题:
(1)不可控性,无法做到随心的加锁和释放锁。
(2)效率比较低下,比如我们现在并发的读两个文件,读与读之间是互不影响的,但如果给这个读的对象使用synchronized来实现同步的话,
那么只要有一个线程进入了,那么其他的线程都要等待。
(3)无法知道线程是否获取到了锁。
而上面synchronized的这些问题,Lock都可以很好的解决,并且jdk1.5以后,还提供了各种锁,例如读写锁,但有一点需要注意,使用synchronized
关键时,无须手动释放锁,但使用Lock必须手动释放锁。下面我们就来学习一下Lock锁。
Lock是一个上层的接口,其原型如下,总共提供了6个方法:
public interface Lock {
// 用来获取锁,如果锁已经被其他线程获取,则一直等待,直到获取到锁
void lock();
// 该方法获取锁时,可以响应中断,比如现在有两个线程,一个已经获取到了锁,另一个线程调用这个方法正在等待锁,但是此刻又不想让这个线程一直在这死等,可以通过
调用线程的Thread.interrupted()方法,来中断线程的等待过程
void lockInterruptibly() throws InterruptedException;
// tryLock方法会返回bool值,该方法会尝试着获取锁,如果获取到锁,就返回true,如果没有获取到锁,就返回false,但是该方法会立刻返回,而不会一直等待
boolean tryLock();
// 这个方法和上面的tryLock差不多是一样的,只是会尝试指定的时间,如果在指定的时间内拿到了锁,则会返回true,如果在指定的时间内没有拿到锁,则会返回false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 释放锁
void unlock();
// 实现线程通信,相当于wait和notify,后面会单独讲解
Condition newCondition();
}
那么这几个方法该如何使用了?前面我们说到,使用Lock是需要手动释放锁的,但是如果程序中抛出了异常,那么就无法做到释放锁,有可能引起死锁,
所以我们在使用Lock的时候,有一种固定的格式,如下:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {// 必须使用try,最后在finally里面释放锁
l.unlock();
}
下面我们来看一个简单的例子,代码如下:
/**
* 描述:Lock使用
*/
public class LockDemo {
// new一个锁对象,注意此处必须声明成类对象,保持只有一把锁,ReentrantLock是Lock的唯一实现类
Lock lock = new ReentrantLock();
public void readFile(String fileMessage){
lock.lock();// 上锁
try{
System.out.println(Thread.currentThread().getName()+"得到了锁,正在读取文件……");
for(int i=0; i<fileMessage.length(); i++){
System.out.print(fileMessage.charAt(i));
}
System.out.println();
System.out.println("文件读取完毕!");
}finally{
System.out.println(Thread.currentThread().getName()+"释放了锁!");
lock.unlock();
}
} public void demo(final String fileMessage){
// 创建若干个线程
ExecutorService service = Executors.newCachedThreadPool();
// 提交20个任务
for(int i=0; i<20; i++){
service.execute(new Runnable() {
@Override
public void run() {
readFile(fileMessage);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// 释放线程池中的线程
service.shutdown();
}
}
Java多线程中Lock的使用的更多相关文章
- java多线程中的三种特性
java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...
- Java多线程中的竞争条件、锁以及同步的概念
竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...
- c#初学-多线程中lock用法的经典实例
本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被 ...
- 多线程中lock用法的经典实例
多线程中lock用法的经典实例 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.它可以把一段代码定义为互斥段(critical section),互斥段在一 ...
- java 多线程中的wait方法的详解
java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...
- java多线程中并发集合和同步集合有哪些?区别是什么?
java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...
- java多线程中最佳的实践方案是什么?
java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...
- c#多线程中Lock()关键字的用法小结
本篇文章主要是对c#多线程中Lock()关键字的用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段 ...
- Java多线程中的常用方法
本文将带你讲诉Java多线程中的常用方法 Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...
随机推荐
- LeetCode(23)Merge k Sorted Lists
题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...
- hihocoder1174 拓扑排序1
#1174 : 拓扑排序·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来. 小Ho:小Hi,你这学期有选 ...
- poj 1995 快速幂
题意:给出A1,…,AH,B1,…,BH以及M,求(A1^B1+A2^B2+ … +AH^BH)mod M. 思路:快速幂 实例 3^11 11=2^0+2^1+2^3 => 3^1*3 ...
- BZOJ 4985: 评分
二分答案 >=key的记为1 f[i]表示令i位置为1所需要的最少的1的个数 队列模拟 #include<cstdio> #include<algorithm> usin ...
- LA 7056 Colorful Toy Polya定理
题意: 平面上给出一个\(N\)个点\(M\)条边的无向图,要用\(C\)种颜色去给每个顶点染色. 如果一种染色方案可以旋转得到另一种染色方案,那么说明这两种染色方案是等价的. 求所有染色方案数 \( ...
- python面试题解析(python基础篇80题)
1. 答:出于编程的喜爱,以及行业本身的前瞻性,创造性,优越性,越是综合的科目越能检验一个人的能力,喜欢这种有挑战的事情. 2. 答:跟随老师学习,以及自己查询资料,结合实战,进行输入输出以及 ...
- 玩App怎么赚钱(二)
紧接上篇文章,谈到App前赚钱的一些门道,其实还有很多了,需要你自己去挖掘App到底有什么价值.有价值的东西就能形成交易,而交易的过程中是用金钱作为流通手段,所以说赚钱没那么高大上,它的本质就是价值的 ...
- Leetcode13--->罗马数字转换为整数
该算法是将罗马数字转换为整数,思路如下:比如IXX,使用临时变量temp保存上一个已经遍历的罗马数字,比如:遍历时是从后往前遍历的:1> 刚开始时,temp = 0; 遍历当前遍历到第一个X,则 ...
- 01-python进阶-拾遗
列表复习append(x)追交到链尾extend(L)追加一个列表 等价于 +=insert(i,x)在位置i处插入xremove(x) 删除一个值为x的元素 如果没有抛出异常sort() 直接修改列 ...
- 《程序员思维修炼》读书笔记——week4
<程序员思维修炼>读书笔记——week4 PB16061441 陈昶金 这周读的是Andy Hunt的著作<程序员思维修炼>,这本书对于我这种刚刚入门的新手很友好,大多是讲一些 ...