`

java 锁对象Lock-同步问题更完美的处理方式(ReadWriteLock)

 
阅读更多
Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我们拿Java线程(二)中的一个例子简单的实现一下和sychronized一样的效果,代码如下:

public class LockTest {
	public static void main(String[] args) {
		final Outputter1 output = new Outputter1();
		new Thread() {
			public void run() {
				output.output("zhangsan");
			};
		}.start();		
		new Thread() {
			public void run() {
				output.output("lisi");
			};
		}.start();
	}
}
class Outputter1 {
	private Lock lock = new ReentrantLock();// 锁对象
	public void output(String name) {
		// TODO 线程输出方法
		lock.lock();// 得到锁
		try {
			for(int i = 0; i < name.length(); i++) {
				System.out.print(name.charAt(i));
			}
		} finally {
			lock.unlock();// 释放锁
		}
	}
}


这样就实现了和sychronized一样的同步效果,需要注意的是,用sychronized修饰的方法或者语句块在代码执行完之后锁自动释放,而用Lock需要我们手动释放锁,所以为了保证锁最终被释放(发生异常情况),要把互斥区放在try内,释放锁放在finally内。
     如果说这就是Lock,那么它不能成为同步问题更完美的处理方式,下面要介绍的是读写锁(ReadWriteLock),我们会有一种需求,在对数据进行读写的时候,为了保证数据的一致性和完整性,需要读和写是互斥的,写和写是互斥的,但是读和读是不需要互斥的,这样读和读不互斥性能更高些,来看一下不考虑互斥情况的代码原型:

public class ReadWriteLockTest {
	public static void main(String[] args) {
		final Data data = new Data();
		for (int i = 0; i < 3; i++) {
			new Thread(new Runnable() {
				public void run() {
					for (int j = 0; j < 5; j++) {
						data.set(new Random().nextInt(30));
					}
				}
			}).start();
		}		
		for (int i = 0; i < 3; i++) {
			new Thread(new Runnable() {
				public void run() {
					for (int j = 0; j < 5; j++) {
						data.get();
					}
				}
			}).start();
		}
	}
}
class Data {	
	private int data;// 共享数据	
	public void set(int data) {
		System.out.println(Thread.currentThread().getName() + "准备写入数据");
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.data = data;
		System.out.println(Thread.currentThread().getName() + "写入" + this.data);
	}	
	public void get() {
		System.out.println(Thread.currentThread().getName() + "准备读取数据");
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "读取" + this.data);
	}
}


部分输出结果:

Thread-1准备写入数据
Thread-3准备读取数据
Thread-2准备写入数据
Thread-0准备写入数据
Thread-4准备读取数据
Thread-5准备读取数据
Thread-2写入12
Thread-4读取12
Thread-5读取5
Thread-1写入12

我们要实现写入和写入互斥,读取和写入互斥,读取和读取互斥,在set和get方法加入sychronized修饰符:

public synchronized void set(int data) {...}	
public synchronized void get() {...}



Thread-0准备写入数据
Thread-0写入9
Thread-5准备读取数据
Thread-5读取9
Thread-5准备读取数据
Thread-5读取9
Thread-5准备读取数据
Thread-5读取9
Thread-5准备读取数据
Thread-5读取9


我们发现,虽然写入和写入互斥了,读取和写入也互斥了,但是读取和读取之间也互斥了,不能并发执行,效率较低,用读写锁实现代码如下:

class Data {	
	private int data;// 共享数据
	private ReadWriteLock rwl = new ReentrantReadWriteLock();	
	public void set(int data) {
		rwl.writeLock().lock();// 取到写锁
		try {
			System.out.println(Thread.currentThread().getName() + "准备写入数据");
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			this.data = data;
			System.out.println(Thread.currentThread().getName() + "写入" + this.data);
		} finally {
			rwl.writeLock().unlock();// 释放写锁
		}
	}	
	public void get() {
		rwl.readLock().lock();// 取到读锁
		try {
			System.out.println(Thread.currentThread().getName() + "准备读取数据");
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "读取" + this.data);
		} finally {
			rwl.readLock().unlock();// 释放读锁
		}
	}
}


部分输出结果:

Thread-4准备读取数据
Thread-3准备读取数据
Thread-5准备读取数据
Thread-5读取18
Thread-4读取18
Thread-3读取18
Thread-2准备写入数据
Thread-2写入6
Thread-2准备写入数据
Thread-2写入10
Thread-1准备写入数据
Thread-1写入22
Thread-5准备读取数据

从结果可以看出实现了我们的需求,这只是锁的基本用法,锁的机制还需要继续深入学习。


转自:http://blog.csdn.net/ghsau/article/details/7461369
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Java线程之锁对象Lock-同步问题更完美的处理方式代码实例

    Java线程之锁对象Lock-同步问题更完美的处理方式代码实例 Java中的锁对象Lock是java.util.concurrent.locks包下的接口,提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。它能以更优雅的方式处理线程...

    Java锁机制详解.pdf

    Java锁机制的发展历经了多个版本的改进,尤其是Java 5.0引入的显示锁(Explicit Locks),提供了一系列比内置锁(synchronized)更灵活的同步手段。 在Java中,内置锁是通过synchronized关键字实现的,而显示锁则是...

    Java资源同步Java资源同步Java资源同步

    在Java开发中,资源同步是一个非常重要且常见的问题,尤其是在多线程环境中,合理地管理资源能够有效提升程序的稳定性和效率。根据提供的标题与描述,本次将深入探讨“Java资源同步”的相关知识点。 #### 1. 资源...

    Java锁的种类以及区别

    在Java编程语言中,锁是一种重要的同步机制,用于控制多个线程对共享资源的访问,防止数据不一致等问题的发生。本文将详细介绍Java中几种常见的锁类型及其之间的区别。 #### 一、公平锁与非公平锁 **1. 公平锁** ...

    java经典面试题目-面经-java-Java语言的进阶概念-常用的库和框架-并发编程-网络编程-Web开发-面经

    Java的锁机制包括内置锁(synchronized)、显式锁(Lock接口)、读写锁(ReadWriteLock)等,适用于不同的同步需求。同步处理线程间的共享数据,而异步则让任务并发执行,等待结果。 AOP(面向切面编程)用于分离...

    Java锁的知识总结及实例代码共7页.pdf.zip

    当一个线程进入某个对象的同步代码块或同步方法时,会自动获取该对象的锁,执行完毕后释放。如果其他线程试图在同一时间进入,它们将被阻塞,直到锁被释放。 1. **内置锁(监视器锁)**: - **synchronized关键字*...

    Java的锁机制的学习和使用

    Java语言提供了多种锁机制,包括`synchronized`关键字、`ReentrantLock`类以及`ReadWriteLock`接口等。 #### 二、synchronized关键字详解 `synchronized`是Java中一种最基本的锁机制,它可以修饰实例方法、静态...

    java中的Lock类和Condition类.docx

    在JDK 1.5及之后的版本中,Lock类作为替代synchronized关键字的一种方式出现,提供了更精细的锁管理机制。 1. **Lock类** - Lock是一个接口,其主要实现类有ReentrantLock(可重入锁)。ReentrantLock不仅具备了...

    homework-ReadWriteLock-KristampsW-main.zip

    读写锁是一种多线程同步机制,用于提高并发性能,特别是在读操作远多于写操作的情景下。在Java中,`java.util.concurrent.locks.ReadWriteLock`接口提供了这种功能,它有两个主要的方法:`readLock()` 和 `writeLock...

    Java concurrency之锁_动力节点Java学院整理

    JUC包在Java 5引入,提供了更为丰富的锁机制和高级同步工具,如Lock接口、ReadWriteLock接口、LockSupport阻塞原语、Condition条件以及相关的抽象类和实现类。 - Lock接口:Lock提供了比`synchronized`更细粒度的...

    java 同步方法

    【Java 同步方法】是Java编程中处理并发和多线程问题的关键技术,用于确保在多线程环境中对共享资源的正确访问。同步方法通过`synchronized`关键字实现,确保同一时间只有一个线程能够执行特定的方法或代码块,从而...

    java常用锁使用demo工程

    在这个工程中,我们可能会看到各种锁的实例,如内置锁(synchronized)、显式锁(java.util.concurrent.locks包中的Lock接口)以及相关的同步工具类。 1. 内置锁(Synchronized): - **同步方法**:通过在方法...

    Java并发篇乐观锁,悲观锁,自旋锁

    本文主要讨论了四种锁类型:乐观锁、悲观锁、自旋锁以及Java中的synchronized同步锁,并深入解析了synchronized锁的内部机制,包括其核心组件、实现方式以及锁的状态。 1. **乐观锁**:乐观锁假设在多线程环境下,...

    提升Java的锁性能Java开发Java经验技巧共5页.p

    - **显式锁(Lock)**:Java并发包`java.util.concurrent.locks`提供了显式锁,如`ReentrantLock`,相比内置锁,它提供了更细粒度的控制,如可中断、公平性等特性。 2. **使用并发容器** - **ConcurrentHashMap**...

    面向Java锁机制的字节码自动重构框架.pdf

    Java语言提供了多种锁机制,包括同步锁(synchronized),可重入锁(ReentrantLock)和读写锁(ReadWriteLock)。这些锁机制是并行程序设计中保证数据访问正确性和程序性能的关键同步控制方式。同步锁是一种内置的锁机制,...

    Java多线程运算集合

    - Java提供了 `java.util.concurrent.locks` 包中的 `Lock` 接口及其实现类,如 `ReentrantLock`,用于更高级别的锁控制。 #### 六、Java线程的交互 - **线程通信**: - Java中的线程间通信主要包括 `wait()`、`...

    panda-demo.zip

    - **概念**:ReadWriteLock是Java中的`java.util.concurrent.locks.ReadWriteLock`接口,它提供了比synchronized更细粒度的锁控制,允许多个读取者同时访问资源,而只允许一个写入者,从而提高了并发性能。...

    同步读锁,异步互斥写锁源码

    3. **读写锁接口(ReadWriteLock)**:提供读锁和写锁的获取与释放方法,如`readLock()`返回读锁实例,`writeLock()`返回写锁实例。 4. **锁的公平性(Fairness)**:`LockDemo`可能支持公平锁和非公平锁的选择,...

    Lock接口与synchronized关键字

    在Java并发编程中,Lock接口与synchronized关键字都是实现同步的重要工具。它们虽然都用于控制多线程对共享资源的访问,但在使用方式、功能特性及灵活性方面存在显著差异。 #### 二、使用方式对比 1. **...

Global site tag (gtag.js) - Google Analytics