Java并发之读写锁Lock和条件阻塞Condition的应用(转载)
2012-09-13 20:46
615 查看
Java 5中提供了另一种实现线程同步或互斥的机制,即使用Lock和Condition。
Lock比传统线程模型中的synchronized方式更加面向对象,也提供了更多可选择的锁机制。与生活中的锁类似,锁本身也是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须使用同一个Lock对象。锁是上在代表要操作的资源的类的内部方法中,而不是线程代码中。
Lock使用示例:
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由JVM控制的,我们只需要上好相应的锁即可。如果代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果代码修改数据,只能有一个人在写,并不能同时读取,那就上写销锁。总之,读的时候上读锁,写的时候上写锁。
Java读写锁示例:
使用
:
Condition的功能类似在传统线程技术中的Object.wait和Object.notity的功能。在等待Condition时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为Condition应该总是在一个循环中被等待,并测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒,但建议应用程序员总是假定这些虚假唤醒可能发生,因此总是在一个循环中等待。
一个锁内部可以有多个Condition,即有多路等待和通知,可以参看Jdk1.5提供的Lock和Condition实现的可阻塞队列的应用案例。在传统的线程机制中一个监视器对象上只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。
JDK文档中提供了一个很不错的示例(http://docs.oracle.com/javase/6/docs/api/ ),用Condition实现一个阻塞队列,代码如下:
转载:http://blog.sina.com.cn/jiangafu
Lock比传统线程模型中的synchronized方式更加面向对象,也提供了更多可选择的锁机制。与生活中的锁类似,锁本身也是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须使用同一个Lock对象。锁是上在代表要操作的资源的类的内部方法中,而不是线程代码中。
Lock使用示例:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; // An example of using Lock. public class LockTest { public static void main(String[] args) { new LockTest().init(); } private void init() { final Outputer outputer = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch(InterruptedException e) { e.printStackTrace(); } outputer.output("aaaaaaaaaaa"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch(InterruptedException e) { e.printStackTrace(); } outputer.output("bbbbbbbbbbb"); } } }).start(); } static class Outputer { private Lock lock = new ReentrantLock(); public void output(String name) { int len = name.length(); lock.lock(); try { for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } finally { lock.unlock(); } } } }
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由JVM控制的,我们只需要上好相应的锁即可。如果代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果代码修改数据,只能有一个人在写,并不能同时读取,那就上写销锁。总之,读的时候上读锁,写的时候上写锁。
Java读写锁示例:
import java.util.Random; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest { public static void main(String[] args) { final MyQueue queue = new MyQueue(); for (int i = 0; i < 3; i++) { new Thread() { public void run() { while (true) { queue.get(); } } }.start(); new Thread() { public void run() { while (true) { queue.put(new Random().nextInt(10000)); } } }.start(); } } } class MyQueue { // 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。 private Object data = null; ReadWriteLock rwl = new ReentrantReadWriteLock(); public void get() { rwl.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to read data!"); Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() + "have read data :" + data); } catch (InterruptedException e) { e.printStackTrace(); } finally { rwl.readLock().unlock(); } } public void put(Object data) { rwl.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to write data!"); Thread.sleep((long) (Math.random() * 1000)); this.data = data; System.out.println(Thread.currentThread().getName() + " have write data: " + data); } catch (InterruptedException e) { e.printStackTrace(); } finally { rwl.writeLock().unlock(); } } }
使用
import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; // Using a ReadWriteLock to implement a cache. public class CacheDemo { private Map < String, Object > cache = new HashMap < String, Object > (); private ReadWriteLock rwl = new ReentrantReadWriteLock(); public static void main(String[] args) { CacheDemo cache = new CacheDemo(); Object obj = cache.getData(""); System.out.println(obj.toString()); } // Get the value from DB if the value does not exist,and then return it. public Object getData(String key) { rwl.readLock().lock(); Object value = null; try { value = cache.get(key); if (value == null) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have acquired // write lock and changed state before we did. if (value == null) { // Here may access Database. // ... value = "Data"; } } finally { rwl.writeLock().unlock(); } rwl.readLock().lock(); } } finally { rwl.readLock().unlock(); } return value; } }
:
Condition的功能类似在传统线程技术中的Object.wait和Object.notity的功能。在等待Condition时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为Condition应该总是在一个循环中被等待,并测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒,但建议应用程序员总是假定这些虚假唤醒可能发生,因此总是在一个循环中等待。
一个锁内部可以有多个Condition,即有多路等待和通知,可以参看Jdk1.5提供的Lock和Condition实现的可阻塞队列的应用案例。在传统的线程机制中一个监视器对象上只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。
JDK文档中提供了一个很不错的示例(http://docs.oracle.com/javase/6/docs/api/ ),用Condition实现一个阻塞队列,代码如下:
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
转载:http://blog.sina.com.cn/jiangafu
相关文章推荐
- Java并发之读写锁Lock和条件阻塞Condition的应用
- Java并发之读写锁Lock和条件阻塞Condition的应用
- Java并发之读写锁Lock和条件阻塞Condition的应用
- 【java并发】条件阻塞Condition的应用
- Java5并发库之条件阻塞Condition的应用
- 【张孝祥并发课程笔记】12:java5条件阻塞Condition的应用
- java5条件阻塞Condition的应用-多路等待通知Lock-Condition使用-笔记整理10
- 【Java多线程与并发库】11.java5条件阻塞Condition的应用
- java多线程之线程并发库条件阻塞Condition的应用
- Java并发之条件阻塞Condition的应用代码示例
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
- java5条件阻塞Condition的应用
- java5条件阻塞Condition的应用(十三)
- Java5线程并发库之LOCK(锁)&CONDITION(条件)实现线程同步通信
- Java多线程与并发应用-(9)-锁lock+条件阻塞conditon实现线程同步通信
- 聊聊高并发(十四)理解Java中的管程,条件队列,Condition以及实现一个阻塞队列
- java基础——多线程(锁lock&&条件阻塞Condition)
- Java多线程与并发应用-(11)-用Lock+Condition实现1,2,3 三个模块按顺序执行。
- java基础——多线程(锁lock&&条件阻塞Condition)
- 线程高级应用-心得7-java5线程并发库中阻塞队列Condition的应用及案例分析