- 浏览: 370333 次
- 性别:
- 来自: Alien
文章分类
最新评论
-
风一样的男人__:
[flash=200,200][url]引用[/url][/f ...
java线程内存模型,线程、工作内存、主内存 -
极乐君:
厉害了,,,请问可以转载到我们专栏吗?会注明来源和地址的~专栏 ...
java线程内存模型,线程、工作内存、主内存 -
zdd001:
Spring 线程池使用 -
zdd001:
Spring 线程池使用 -
u014663756:
看了三行就知道是我想要的!!
java线程内存模型,线程、工作内存、主内存
两种互斥锁机制:
1、synchronized
2、ReentrantLock
ReentrantLock是jdk5的新特性,采用ReentrantLock可以完全替代替换synchronized传统的锁机制,而且采用ReentrantLock的方式更加面向对象,也更加灵活,网上有很多关于对比两者锁方式的文章,这里就不多口舌了,大家baidu、google一下就水落石出了。在本博客中也写关于这两种锁方式实现的经典例子《生产者消费者》。
synchronized方式:《java线程:三种方式实现生产者消费者问题_1》
ReentranLock方式:《java线程:三种方式实现生产者消费者问题_2》
关于读写锁,用语言解释不如直接用代码诠释,以下通过两个例子讲述读写锁以及读写锁的使用:
例子1:
[java] view plaincopy
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.locks.ReadWriteLock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- /**
- * @author amber2012
- *
- * 读写锁:ReadWriteLock
- *
- * 在多线程的环境下,对同一份数据进行读写,会涉及到线程安全的问题。比如在一个线程读取数据的时候,另外一个线程在
- * 写数据,而导致前后数据的不一致性;一个线程在写数据的时候,另一个线程也在写,同样也会导致线程前后看到的数据的
- * 不一致性。
- *
- * 这时候可以在读写方法中加入互斥锁,任何时候只能允许一个线程的一个读或写操作,而不允许其他线程的读或写操作,这
- * 样是可以解决这样以上的问题,但是效率却大打折扣了。因为在真实的业务场景中,一份数据,读取数据的操作次数通常高
- * 于写入数据的操作,而线程与线程间的读读操作是不涉及到线程安全的问题,没有必要加入互斥锁,只要在读-写,写-写期
- * 间上锁就行了。
- *
- * 对于这种情况,读写锁则最好的解决方案!
- *
- * 读写锁的机制:
- * "读-读"不互斥
- * "读-写"互斥
- * "写-写"互斥
- *
- * 即在任何时候必须保证:
- * 只有一个线程在写入;
- * 线程正在读取的时候,写入操作等待;
- * 线程正在写入的时候,其他线程的写入操作和读取操作都要等待;
- *
- * 以下是一个缓存类:用于演示读写锁的操作:重入、降级
- */
- public class CachedData {
- // 缓存都应该是单例的,在这里用单例模式设计:
- private static CachedData cachedData = new CachedData();
- private final ReadWriteLock lock = new ReentrantReadWriteLock();//读写锁
- private Map<String, Object> cache = new HashMap<String, Object>();//缓存
- private CachedData(){
- }
- public static CachedData getInstance(){
- return cachedData;
- }
- // 读取缓存:
- public Object read(String key) {
- lock.readLock().lock();
- Object obj = null;
- try {
- obj = cache.get(key);
- if (obj == null) {
- lock.readLock().unlock();
- // 在这里的时候,其他的线程有可能获取到锁
- lock.writeLock().lock();
- try {
- if (obj == null) {
- obj = "查找数据库"; // 实际动作是查找数据库
- // 把数据更新到缓存中:
- cache.put(key, obj);
- }
- } finally {
- // 当前线程在获取到写锁的过程中,可以获取到读锁,这叫锁的重入,然后导致了写锁的降级,称为降级锁。
- // 利用重入可以将写锁降级,但只能在当前线程保持的所有写入锁都已经释放后,才允许重入 reader使用
- // 它们。所以在重入的过程中,其他的线程不会有获取到锁的机会(这样做的好处)。试想,先释放写锁,在
- // 上读锁,这样做有什么弊端?--如果这样做,那么在释放写锁后,在得到读锁前,有可能被其他线程打断。
- // 重入————>降级锁的步骤:先获取写入锁,然后获取读取锁,最后释放写入锁(重点)
- lock.readLock().lock();
- lock.writeLock().unlock();
- }
- }
- } finally {
- lock.readLock().unlock();
- }
- return obj;
- }
- }
例子2:
[java] view plaincopy
- import java.util.Map;
- import java.util.TreeMap;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReadWriteLock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- import javax.xml.crypto.Data;
- /**
- * @author amber2012
- *
- * jdk文档中关于ReentrantReadWriteLock类使用的一个很好的例子,以下是具体的介绍:
- *
- * 在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。通常,在预期 collection
- * 很大,读取者线程访问它的次数多于写入者线程,并且 entail 操作的开销高于同步开销时,这很值得一试。例如,以下
- * 是一个使用 TreeMap 的类,预期它很大,并且能被同时访问。
- */
- public class RWDictionary {
- private final Map<String, Data> map = new TreeMap<String, Data>();
- private final ReadWriteLock rwl = new ReentrantReadWriteLock();
- private final Lock readLock = rwl.readLock();
- private final Lock writeLock = rwl.writeLock();
- public Data get(String key) {
- readLock.lock();
- try {
- return map.get(key);
- } finally {
- readLock.unlock();
- }
- }
- public String[] allKeys() {
- readLock.lock();
- try {
- return (String[]) map.keySet().toArray();
- } finally {
- readLock.unlock();
- }
- }
- public Data put(String key, Data value) {
- writeLock.lock();
- try {
- return map.put(key, value);
- } finally {
- writeLock.unlock();
- }
- }
- public void clear() {
- writeLock.lock();
- try {
- map.clear();
- } finally {
- writeLock.unlock();
- }
- }
- }
发表评论
-
Spring 线程池使用2
2013-04-25 18:41 1148<!-- 配置异步线程执行器 --> < ... -
java synchronized与lock区别 转
2013-03-20 01:59 1053java synchronized与lock区别 ... -
java并发编程实践笔记(转)
2012-11-28 01:14 934一、 保证线程安全的 ... -
并发集合类ConcurrentSkipListSet
2012-11-24 03:26 5618ConcurrentSkipListSet Concu ... -
Amdahl 定律 (阿姆达尔定律)
2012-11-24 02:14 2066有些问题使用越多的资源就能越快地解决——越多的工人参 ... -
java线程内存模型,线程、工作内存、主内存
2012-11-24 02:08 18187java线程内存模型 线程、工作内存、主内存三者之间的 ... -
线程同步与异步
2012-11-22 23:53 2476Java中的线程同步与 ... -
Java 并发核心编程(转)
2012-11-06 10:16 1022Java 并发核心编程(转) Java 并发核心编程 ... -
java线程:关于Callable和Future的简单使用:有返回值的线程
2012-11-06 09:19 1965分类: java_线程2012-07-03 19 ... -
java数据结构:ConcurrentSkipListSet<E>与CopyOnWriteArraySet<E>
2012-11-06 09:20 5863分类: java_数据结构 java_线程201 ... -
java线程:信号量
2012-11-06 09:20 884Java 信号量 Semaphore 介绍 Semaphore ... -
java线程:一个死锁的小程序
2012-11-06 09:20 2701死锁是这样一种 ... -
java线程:三种方式实现生产者消费者问题_3
2012-11-05 17:34 1306java线程:三种方式 ... -
java线程:几个实用的线程工具类
2012-11-05 15:15 8364java线程:几个实用的线程工具类 分类: ... -
java线程:三种方式实现生产者消费者问题_2
2012-11-05 14:26 1122java线程:三种方式实现生产者消费者问题_2 ... -
java线程:三种方式实现生产者消费者问题_1
2012-11-05 14:22 1149java线程:三种方式实现生产者消费者问题_1 ... -
java ExecutorService 线程池Callable 和 Future接口
2012-08-29 21:10 1168javaEye转载(java多线程 Callable 的实现) ... -
线程并发
2012-03-31 15:41 10421:>内存模型 究竟什么是内存模型?内存模型描述了程序中 ... -
特殊的队列:BlockingQueue 使用(转)
2012-03-28 14:49 1061本例介绍一个特殊的队列:BlockingQueue,如果Blo ... -
Spring 线程池使用
2012-03-28 12:47 26087Spring 线程池使用 /** * */ 一个日志管理 ...
相关推荐
- **文件操作**:在多个线程或进程中,如果需要对同一个文件进行读写操作,使用互斥锁可以防止数据的混乱,确保每次只有一个线程或进程进行读写。 - **全局变量**:当多个线程需要修改全局变量时,互斥锁能确保...
本文将深入探讨标题和描述中提及的各种锁,包括乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁以及行级锁。 1. **乐观锁**:乐观锁假设多线程环境中的冲突较少,所以在读取数据时不加锁,只有...
- **互斥锁**:互斥锁确保同一时间只有一个线程可以访问资源,其他试图获取锁的线程必须等待锁被释放。在Java中,通常通过`java.util.concurrent.locks.ReentrantLock`实现。 - **信号量**:信号量允许多个线程...
Java 读写锁是Java并发编程中的一种重要机制,它为多线程环境下的数据访问提供了更为精细的控制。在Java的`java.util.concurrent.locks`包中,`ReentrantReadWriteLock`类实现了读写锁的功能。这个锁允许多个读取者...
#### Java线程:线程的同步与锁 在多线程环境中,为防止多个线程同时访问共享资源导致的数据不一致,需要进行线程同步。Java提供了多种同步机制,包括synchronized关键字、Lock接口及其实现类(如ReentrantLock)以及...
2. **ReentrantLock(可重入锁)**:这是 Java Concurrency API 提供的一个高级锁,与 synchronized 相比,ReentrantLock 提供了更细粒度的控制,例如可中断的等待、公平锁和非公平锁等特性。可重入性意味着线程可以...
Java线程安全与锁是多线程编程中的关键概念,主要涉及到并发环境下对共享资源的访问控制。在Java中,线程安全问题主要是由于多个线程同时访问并修改同一份数据,导致数据不一致或者出现意外的行为。为了解决这个问题...
关于读写锁算法的Java实现及思考,是一个深入探讨了多线程环境下资源访问控制机制的主题。在现代软件开发中,尤其是并发编程领域,读写锁(ReadWriteLock)是一种非常重要的同步工具,它允许多个线程同时进行读操作...
Java还有其他类型的锁,如ReentrantLock(可重入锁,功能与Synchronized类似但更灵活)、Semaphore(信号量,控制同时访问特定资源的线程数量)和ReadWriteLock(读写锁,允许多个读线程同时访问,但写操作互斥)等...
除了以上所述的锁类型外,Java还提供了一些与锁相关的高级特性,例如锁粗化和锁消除。锁粗化是指将多个细粒度的锁操作合并为一个粗粒度的锁操作,以减少线程在获取和释放锁时产生的开销。锁消除是指在运行时,编译器...
首先,我们需要了解锁的基本类型:互斥锁(Mutex)和读写锁(Read-Write Lock)。互斥锁提供独占式访问,即一次只允许一个线程访问共享资源,保证了写操作的安全性。而读写锁则进一步区分了读取和写入操作,允许多个...
当一个线程获取了互斥锁,其他尝试获取该锁的线程将被阻塞,直到锁被释放。`lock()`, `unlock()`和`try_lock()`是互斥锁的主要操作。 3. **条件变量(Condition Variable)** 条件变量允许线程在满足特定条件时...
总结来说,读写锁分离模式通过分离读锁和写锁,使得在多线程环境下,读操作可以并行执行,写操作保持互斥,从而优化了并发访问的效率。Java的`java.util.concurrent.locks.ReadWriteLock`接口提供了一种标准的实现...
在《秒杀多线程系列》的前十五篇中介绍多线程的相关概念,多线程同步互斥问题《秒杀多线程第四篇一个经典的多线程同步问题》及解决多线程同步互斥的常用方法——关键段、事件、互斥量、信号量、读写锁。为了让大家...
在Java并发编程中,读写锁是用于优化多线程访问共享资源的一种机制,它可以提高对数据的并发访问效率。本文将深入探讨Java中的两种读写锁:ReentrantReadWriteLock和StampedLock,并分析它们的工作原理、特点以及...
3. Lock接口与ReentrantLock类:提供了比synchronized更灵活的锁机制,支持公平锁、非公平锁、读写锁等。 4. volatile与synchronized的区别:volatile只能保证可见性,而synchronized能保证可见性和原子性。 四、...
在Java中,实现读写线程的同步通常有两种策略:互斥访问和读者-写者问题。"读者优先"的策略是一种解决读者-写者问题的方式,它允许同时有多个读者访问资源,但当有写者时,所有读写操作都必须暂停,直到写者完成其...
8. **线程同步原语**:除了上述的Mutex和Semaphore,还有其他的同步原语,如条件变量、读写锁等,它们在不同场景下各有优势。 9. **线程的生命周期**:线程创建后,会有启动、执行、等待、休眠、恢复、结束等状态。...
线程锁有几种不同的类型,包括互斥锁(Mutex)、读写锁(Read-Write Locks)、自旋锁(Spinlock)和条件变量(Condition Variables)。每种锁都有其特定的适用场景: 1. **互斥锁**:最基础的线程锁,确保任何时候...
### 第20章 Part3:多线程互斥与协作 #### 一、互斥(Mutual Exclusion) 互斥是指在线程编程中确保多个线程不会同时访问同一资源的技术。这种技术非常重要,因为如果不加以控制,多个线程对共享资源的并发访问...