我们在处理并发操作的时候经常使用锁机制,大家常用的synchronized和Lock.
1.二者使用方式有所不同:
synchronized可以在方法前或者代码块中,synchronized是java中的内置锁,由jvm控制锁的释放。
Lock使用在代码块中,加锁之后需要显示的释放,一般在finally中释放锁,主要有两种锁ReentrantLock和ReentrantReadWriteLock。
2.二者都是互斥锁,也就是一次只能有一个对象持有该锁。
3.synchronized原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着其 他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。
Lock采用的是乐观锁方式,所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。是非阻塞的。
一般情况下我们使用synchronized就可以满足并发控制,对应高性能的锁机制,我们可以使用ReentrantLock-可重入锁。
java.util.concurrent提供了支持并发数据结构的操作,通过这些我们也可以了解ReentrantLock使用的情形。
ConcurrentHashMap:采用ReentrantLock进行并发控制。
LinkedBlockingDeque:双向阻塞队列,可以作为栈使用,采用ReentrantLock进行并发控制。
LinkedBlockingQueue:阻塞队列,采用ReentrantLock进行并发控制。
如:
/** Lock held by take, poll, etc */
private final ReentrantLock takeLock = new ReentrantLock();
/** Wait queue for waiting takes */
private final Condition notEmpty = takeLock.newCondition();
对于阻塞队列,主要是使用take()方法:返回并且移除队列头部元素,当队列中没有可用元素时,处于阻塞等待状态。
源代码如:
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (count.get() == 0) {
notEmpty.await();
}
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
可用看到,该方法通过可重入锁ReentrantLock进行并发控制的。其中Condition的
notEmpty.signal()表示唤醒等待中的线程,notEmpty.await()使当前的线程处于等待状态,直到被唤醒或者被中断。
分享到:
相关推荐
1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...
java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...
java并发工具包 java.util.concurrent中文版-带书签版
java并发工具包 java.util.concurrent中文版pdf
Tomcat内存溢出的解决方法(java.util.concurrent.ExecutionException:java.lang.OutOfMemoryError),内附解决方案!
java.util.concurrent系列文章(1) java.util.concurrent系列文章(1) java.util.concurrent系列文章(1) java.util.concurrent系列文章(1)
1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...
java.util.concurrent总体概览图。 收取资源分3分。需要的同学可以下载一下。 java.util.concurrent主要包括5个部分executor,colletions,locks,atomic,tools。 该图详细的列举了并发包下面的结构,包含所有接口和...
Java 并发工具包 java.util.concurrent 用户指南 中英文对照阅读版 pdf
本文通过对数据压缩算法的简要介绍,然后以详细的示例演示了利用java.util.zip包实现数据的压缩与解压,并扩展到在网络传输方面如何应用java.util.zip包现数据压缩与解压
如何启动:以win7系统为例,最好jdk8 1.打开cmd,cd到jdk的path,本机是:cd C:\Java\jdk6\bin ...java -cp D:\javaConcurrentAnimated.jar vgrazi.concurrent.samples.launcher.ConcurrentExampleLauncher
Java并发编程工具包java.util.concurrent的UML类结构图 PDF
JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用
主要介绍了java.util.concurrent.ExecutionException 问题解决方法的相关资料,需要的朋友可以参考下
java.util.concurrent系列文章(2) java.util.concurrent系列文章(2) java.util.concurrent系列文章(2) java.util.concurrent系列文章(2)
java.util.ConcurrentModificationException 异常问题详解1
一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用。该类库不提供远程的消息功能,其设计的宗旨是实现一个内存中的消息传递机制. 主要特点有: * All ...
详细介绍了java.util.logging.Logger的用法和结构,对如果扩展Logger起到抛砖引玉的作用!尊重劳动成果,亲下载了要给个评价!
花了一段时间辛苦整理的ppt,与大家分享,请提出您的宝贵意见。
Exception in thread “main“ java.util.InputMismatchException