Java Design Demo--JAVA Lock锁 读写锁ReadWriteLock

                                                                                     前言

多个线程对单一变量进行进行读取和赋值的操作会引发同步的问题

如下图5个线程中4个线程对1个变量i进行读操作

1个线程对i进行自加1操作。红圈处就出现了数据不正常情况。




于是我们加入了synchronized关键字耗时4000毫秒 如下

public static class ReadWriteService{                                                                                                                                                          //以下使用非读写锁的传统示例synchronized  耗时4000                                                                                   	int testNum = 0;
		public synchronized int get() {
			int i = -1;
			try {
				Thread.sleep(10);//耗时
				i = testNum;
			} catch (Exception e) {
			} finally {
			}
			return i;

		}
		
		
		public synchronized void put(int num) {
			try {
				Thread.sleep(20);//耗时
				testNum = num;
				System.out.println("写入" + this.get());
			} catch (Exception e) {
			} finally {

			}
		}                                                                                                                                         }





                                                                                             正题

过去我们对一个文件读写需要同步,后来发觉

我们有N个线程读取数据的时候,可以不需要同步

只有存数据的时候需要同步。

这在JAVA1.5以前是无法做到的。JAVA加入了Lock对象 其子类ReadWriteLock可以轻松帮我们实现该方案。

(Lock的使用方法与synchronized基本相同,但是更加面向对象。和更多新功能)

public void run() {
		// TODO Auto-generated method stub
		synchronized (this) {
			//doing something
		}
	}
等价于以下代码。
Lock lock=new ReentrantLock();
	@Override
	public void run() {
		// TODO Auto-generated method stub
		lock.lock();
		//doing something
		lock.unlock();
}

继续关于读写锁的主题,我们可以设计一个代码。

开启5个线程,4个线程进行读操作,1个线程进行写操作
以下是代码示例

package demo.lock;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {

	static int testNum = 0;
	static long beginTime = System.currentTimeMillis();
	


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final ReadWriteService rw = new ReadWriteService();
		//开启5个线程
		for (int i = 0; i < 5; i++) {
			final int id = i;
			new Thread() {
				public void run() {
					//直到计数达到100
					while (testNum <= 100) {
						//线程中的4个读取数据       else中的一个1个写入数据
						if (id < 4) {
							System.out.println("读取" + rw.get() + "消耗时间  "
									+ (System.currentTimeMillis() - beginTime));
						} else {
							rw.put(testNum++);

						}
					}
				}
			}.start();
		}

	}

	//将同步的代码写在同一个类中体现,面向对象,内聚性,封装性。
	public static class ReadWriteService{
		//读写锁   读与读之间不互斥,读与写互斥。
		ReadWriteLock rwLock = new ReentrantReadWriteLock();
		//测试用的同步数据变量
		int testNum = 0;

		//以下使用读写锁的示例  耗时3000
		public  int get() {
			int i = -1;
			rwLock.readLock().lock();
			try {
				Thread.sleep(10);//耗时
				i = testNum;
			} catch (Exception e) {
				// TODO: handle exception
			} finally {
				rwLock.readLock().unlock();

			}
			return i;

		}

		public  void put(int num) {
			rwLock.writeLock().lock();
			try {
				Thread.sleep(20);//耗时
				testNum = num;
				System.out.println("写入" + this.get());
				
			} catch (Exception e) {
				// TODO: handle exception
			} finally {
				rwLock.writeLock().unlock();
			}
		}
		
		//以下使用非读写锁的传统示例synchronized  耗时4000
//		public synchronized int get() {
//			int i = -1;
//			try {
//				Thread.sleep(10);//耗时
//				i = testNum;
//			} catch (Exception e) {
//			} finally {
//			}
//			return i;
//
//		}
		
		
//		public synchronized void put(int num) {
//			try {
//				Thread.sleep(20);//耗时
//				testNum = num;
//				System.out.println("写入" + this.get());
//			} catch (Exception e) {
//			} finally {
//
//			}
//		}

	}
}




读写锁在多线程 高并发 缓存系统中常常会使用到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值