【java多线程】ConCurrent并发包 - Lock详解
synchronized的缺陷
- 获取锁的线程执行完该段代码,线程会释放占有的锁;
- 线程执行发生异常,此时JVM会让线程自动释放锁。
concurrent.locks包下常用类
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
- lock()方法用来获取锁。
- tryLock()尝试获取锁,如果成功则返回true,失败返回false(其他线程已占有锁)。这个方法会立即返回,在拿不到锁时也不会等待。
- tryLock(long time, TimeUnit unit)方法和tryLock()方法类似,只不过在拿不到锁时等待一定的时间,如果超过等待时间还拿不到锁就返回false。
- lockInterruptibly() 方法比较特殊,当通过这个方法获取锁时,如果该线程正在等待获取锁,则它能够响应中断。也就是说,当两个线程同时通过 lockInterruptibly()获取某个锁时,假如线程A获得了锁,而线程B仍在等待获取锁,那么对线程B调用interrupt()方法可以中 断B的等待过程。
// lock()的使用
Lock lock = ...;
lock.lock();
try{
//处理任务
}catch(Exception ex){ }finally{
lock.unlock(); //释放锁
}
// tryLock()的使用
Lock lock = ...;
if(lock.tryLock()) {
try{
//处理任务
}catch(Exception ex){ }finally{
lock.unlock(); //释放锁
}
}else {
//如果不能获取锁,则直接做其他事情
}
// lockInterruptibly()的使用
public void method() throws InterruptedException {
lock.lockInterruptibly();
try {
//.....
}
finally {
lock.unlock();
}
}
使用synchronized关键字,当线程处于等待锁的状态时,是无法被中断的,只能一直等待。
public class Test {
private ArrayList<Integer> arrayList = new ArrayList<Integer>();
private Lock lock = new ReentrantLock(); //注意这个地方
public static void main(String[] args) {
final Test test = new Test();
new Thread(){
public void run() {
test.insert(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
test.insert(Thread.currentThread());
};
}.start();
}
public void insert(Thread thread) {
lock.lock();
try {
System.out.println(thread.getName()+"得到了锁");
for(int i=0;i<5;i++) {
arrayList.add(i);
}
} catch (Exception e) {
// TODO: handle exception
}finally {
System.out.println(thread.getName()+"释放了锁");
lock.unlock();
}
}
}
例2, lockInterruptibly()响应中断的使用方法:
public class Test {
private Lock lock = new ReentrantLock();
public static void main(String[] args) {
Test test = new Test();
MyThread thread1 = new MyThread(test);
MyThread thread2 = new MyThread(test);
thread1.start();
thread2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread2.interrupt();
}
public void insert(Thread thread) throws InterruptedException{
lock.lockInterruptibly(); //注意,如果需要正确中断等待锁的线程,必须将获取锁放在外面,然后将InterruptedException抛出
try {
System.out.println(thread.getName()+"得到了锁");
long startTime = System.currentTimeMillis();
for( ; ;) {
if(System.currentTimeMillis() - startTime >= Integer.MAX_VALUE)
break;
//插入数据
}
}
finally {
System.out.println(Thread.currentThread().getName()+"执行finally");
lock.unlock();
System.out.println(thread.getName()+"释放了锁");
}
}
}
class MyThread extends Thread {
private Test test = null;
public MyThread(Test test) {
this.test = test;
}
@Override
public void run() {
try {
test.insert(Thread.currentThread());
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"被中断");
}
}
}
3. ReadWriteLock
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*/
Lock readLock();
/**
* Returns the lock used for writing.
*/
Lock writeLock();
}
readLock()用来获取读锁,writeLock()用来获取写锁。也就是将文件的读写操作分开,分成两个锁来分配给线程,从而使多个线程可以同时进行读操作。ReentrantReadWriteLock是它的实现类。
public class Test {
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public static void main(String[] args) {
final Test test = new Test();
new Thread(){
public void run() {
test.get(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
test.get(Thread.currentThread());
};
}.start();
}
public void get(Thread thread) {
rwl.readLock().lock();
try {
long start = System.currentTimeMillis();
while(System.currentTimeMillis() - start <= 1) {
System.out.println(thread.getName()+"正在进行读操作");
}
System.out.println(thread.getName()+"读操作完毕");
} finally {
rwl.readLock().unlock();
}
}
}
【java多线程】ConCurrent并发包 - Lock详解的更多相关文章
- ConCurrent并发包 - Lock详解(转)
synchronized的缺陷 我们知道,可以利用synchronized关键字来实现共享资源的互斥访问.Java 5在java.util.concurrent.locks包下提供了另一种来实现线 ...
- java.util.concurrent.atomic 类包详解
java.util.concurrent包分成了三个部分,分别是java.util.concurrent.java.util.concurrent.atomic和java.util.concurren ...
- 【Java多线程】Executor框架的详解
在Java中,使用线程来异步执行任务.Java线程的创建与销毁需要一定的开销,如果我们为每一个任务创建一个新线程来执行,这些线程的创建与销毁将消耗大量的计算资源.同时,为每一个任务创建一个新线程来执行 ...
- Java多线程Callable和Future类详解
public interface Callable<V> 返回结果并且可能抛出异常的任务.实现者定义了一个不带任何参数的叫做 call 的方法 public in ...
- Java线程创建形式 Thread构造详解 多线程中篇(五)
Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...
- Java并发:多线程和java.util.concurrent并发包总结
多线程和java.util.concurrent并发包 转载:
- java的集合框架最全详解
java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...
- java线程池的使用与详解
java线程池的使用与详解 [转载]本文转载自两篇博文: 1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html ...
- Java多线程--JDK并发包(2)
Java多线程--JDK并发包(2) 线程池 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. JDK有一套Executor框架,大概包括Executor.Ex ...
随机推荐
- 系统管理命令之w
区别于who命令,w命令不仅可以看到登录服务器的用户信息,而且可以看到这些用户做了什么 1.查看该命令的帮助信息. # w --help 2.查看该命令的版本信息. # w --version 3 ...
- Python 字符串转换为日期
应用程序接受字符串格式的输入,但是你想将它们转换为datetime 对象以便在上面执行非字符串操作. 使用Python 的标准模块datetime 可以很容易的解决这个问题.比如: >>& ...
- springcloud11----turbine
package com.itmuch.cloud; import org.springframework.boot.SpringApplication; import org.springframew ...
- xlrd基本操作
#coding=utf-8import xlrd def read_excel(): workbook = xlrd.open_workbook('people.xlsx') sheet2 = wor ...
- css 基础 - 3
css 基础 - 3 20161128 一. 元素的距离计算 1,两个水平方向的容器s1,s2之间的距离计算为s: s = s1的margin-right + s2的margin-left(+默认 ...
- linux find/grep 与cat联合使用
find ./ -name file_name.txt | xargs cat >> file_name.txt
- Linux 用户和组的 添加/删除
1.建用户:adduser phpq //新建phpq用户passwd phpq //给phpq用户设置密码 2.建工作组groupadd test //新建test工作组 3.新建用户同时增加工作组 ...
- Mac adb 安装
一.下载Android studio https://developer.android.google.cn/studio/ 二.安装 首先移动 弹出下面弹框,直接点击OK 提示无法访问Android ...
- Apache-commons-io包的使用及常用方法
首先,我们要下载FileUtils相关的Apache-commons-io jar包以及api文档.FileUtils类库的下载页面在: http://commons.apache.org/prope ...
- java线程中的interrupt,isInterrupt,interrupted方法
在java的线程Thread类中有三个方法,比较容易混淆,在这里解释一下 (1)interrupt:置线程的中断状态 (2)isInterrupt:线程是否中断 (3)interrupted:返回线程 ...