线程同步:读写锁(四)
来源:互联网 发布:linux下svn 钩子函数 编辑:程序博客网 时间:2024/05/01 08:43
- 使用synchronized关键字
- 使用ReadWriteLock接口
并发编程中有一个典型的问题是生产者-消费者(Producer-Consumer)问题。我们有一个数据缓冲区,一个或者多个生产者将数据存入这个缓冲区,一个或者多个数据消费者将数据从缓冲区中取走。
使用synchronized关键字
只是用synchronized关键字会有诸多限制。如果缓冲区是满的,生产者不能再放入新的数据,如果缓冲区是空的,消费者不能取到数据。
对于这些场景java在Object类中提供了wait()、notify()、notifyAll()方法
/** * @Desciption 缓冲区 * * @Author SuFH */public class EventStorage { private int maxSize; private LinkedList<Long> storage; public EventStorage(int max) { //初始化缓冲区 this.maxSize = max; this.storage = new LinkedList<Long>(); } public synchronized void set() { while (storage.size() == maxSize) { try { wait();//挂起当前同步代码块 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } storage.add(System.currentTimeMillis()); System.out.printf("Set: %d\n", storage.size()); // notify();//唤醒一个正在等待该对象的线程,但需要确定不会造成死锁 notifyAll();// 唤醒所有正在等待该对象的线程。 } public synchronized void get() { while (storage.size() == 0) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.printf("Get: %d : %s\n", storage.size(), storage.poll()); notifyAll(); }}
执行:
public class Test { public static void main(String[] args) { EventStorage storage = new EventStorage(10); Producer producer = new Producer(storage); Thread thread = new Thread(producer); Consumer consumer = new Consumer(storage); Thread thread2 = new Thread(consumer); thread.start(); thread2.start(); }}class Producer implements Runnable { private EventStorage storage; public Producer(EventStorage storage) { super(); this.storage = storage; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 100; i++) { this.storage.set(); System.out.println("Producer---"+i); } }}class Consumer implements Runnable { private EventStorage storage; public Consumer(EventStorage storage) { super(); this.storage = storage; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 100; i++) { this.storage.get(); System.out.println("Consumer---"+i); } }}
数据存储的EventStorage类中的set()和get()。
set()方法检查存储列表storage是否还有空间,如果满了,调用wait()挂起线程释放控制这个代码块的对象,等待空余空间出现。该代码块的唤醒却决于其他线程调用当前对象的notifyAll()唤醒等待线程来竞争锁。
get()与之不同之处在于条件是判别空间中无数据则挂起。
使用ReadWriteLock接口
ReadWriteLock与它的唯一实现类ReentrantReadWriteLock。这个类有两个锁分别是读操作锁与写操作锁。其中读操作锁允许多个线程同时访问,但是写操作锁至允许一个线程进行访问,并且在进行写操作时,不能进行读操作
/** * @Desciption 缓冲区 * * @Author SuFH */public class PricesInfo { private double prices1; private double prices2; private ReadWriteLock lock; public PricesInfo() { this.prices1 = 0.1; this.prices2 = 0.2; this.lock = new ReentrantReadWriteLock(); } /**读操作 * @return prices1 */ public double getPrices1() { lock.readLock().lock(); double value=prices1; lock.readLock().unlock(); return value; } /**读操作 * @return prices2 */ public double getPrices2() { lock.readLock().lock(); double value=prices2; lock.readLock().unlock(); return value; } /**写操作 * @param prices1 * @param prices2 */ public void setPrices(double prices1, double prices2) { lock.writeLock().lock(); this.prices1 = prices1; this.prices2 = prices2; lock.writeLock().unlock(); }}
执行:
public class Test { public static void main(String[] args) { PricesInfo info = new PricesInfo(); Read[] reads = new Read[5]; Thread[] thread = new Thread[5]; for (int i = 0; i < 5; i++) { reads[i] = new Read(info); thread[i]=new Thread(reads[i]); } Writer writer=new Writer(info); Thread thread2=new Thread(writer); for (int i = 0; i < 5; i++) { thread[i].start(); } thread2.start(); }}class Read implements Runnable { private PricesInfo info; public Read(PricesInfo info) { // TODO Auto-generated constructor stub this.info = info; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 10; i++) { System.out.printf("%s Price 1: %f\n", Thread.currentThread().getName(), this.info.getPrices1()); System.out.printf("%s Price 2: %f\n", Thread.currentThread().getName(), this.info.getPrices2()); } }}class Writer implements Runnable { private PricesInfo info; public Writer(PricesInfo info) { this.info = info; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 3; i++) { System.out.println("Writer: Attempt to modify the price."); this.info.setPrices(Math.random()*10,Math.random()*5); System.out.println("Writer: Prices have been modfied."); try { Thread.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
阅读全文
0 0
- 线程同步:读写锁(四)
- Java线程(四):JUC包线程互斥与同步以及读写锁
- 线程同步-读写锁
- Linux入门:线程同步与互斥(四)——读写锁
- 2线程同步:读写锁
- Linux线程同步-----读写锁
- 线程同步之读写锁
- linux多线程学习笔记四---线程同步之互斥锁、读写锁和条件变量
- Windows线程同步之Slim读写锁(SRWLock)
- Linux线程同步之读写锁(rwlock)
- Linux线程同步之读写锁(rwlock)
- Linux线程同步之读写锁(rwlock)
- Windows线程同步之Slim读写锁(SRWLock)
- C# 线程同步(6)- 读写锁 ReaderWriterLock
- Linux线程同步之读写锁(rwlock)
- Linux多线程基础学习(五)线程同步-读写锁
- Linux线程同步之读写锁(rwlock)
- 关于线程(四)线程同步
- python-028
- UVa11800
- Linux 变量的介绍和创建 —— env,set,export 命令
- knockout 数组的处理
- Test 2017.10.11
- 线程同步:读写锁(四)
- iOS 关于Category
- 统计学习方法(五)
- 电商后台
- 远程访问控制-ssh命令
- sshd服务
- python 点边界处理
- 几种常用的排序算法(快速排序,希尔排序,堆排序,选择排序,冒泡排序)
- android 控件1