`

java多线程编程——显示锁ReadWriteLock(二)

阅读更多
当需要对集合同时进行写入和读取操作时,如果多线程同时操作会出现异常,那么现在利用ReadWriteLock显示锁,可以在写入量比较小,读取量比较大的场景中,方便的实现上述功能。

package test;

import java.util.Calendar;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 可重入读写锁
 *
 * @author Administrator
 *
 */
@SuppressWarnings("all")
public class ReadWriteLockDemo {
	private ReentrantReadWriteLock lock = null;
	// 读锁
	private Lock readLock = null;
	// 写锁
	private Lock writeLock = null;
	public int key = 100;
	public int index = 100;
	// 线程共享数据
	public Map<Integer, String> dataMap = null;

	public ReadWriteLockDemo() {
		// 创建公平的可重入读写锁
		lock = new ReentrantReadWriteLock(true);
		readLock = lock.readLock();
		writeLock = lock.writeLock();
		dataMap = new TreeMap<Integer, String>();
	}

	public static void main(String[] args) {
		ReadWriteLockDemo test = new ReadWriteLockDemo();
		// 第一次获取写入锁
		test.writeLock.lock();
		System.out.println("线程" + Thread.currentThread().getName() + "第一次获取写入锁");
		// 第二次获取写入锁(这就是可重入的含义)
		test.writeLock.lock();
		System.out.println("线程" + Thread.currentThread().getName() + "第二次获取写入锁");

		test.readLock.lock();
		System.out.println("线程" + Thread.currentThread().getName() + "第一次获取读取锁");

		test.readLock.lock();
		System.out.println("线程" + Thread.currentThread().getName() + "第二次获取读取锁");

		test.readLock.lock();
		System.out.println("线程" + Thread.currentThread().getName() + "第三次获取读取锁");

		test.writeLock.unlock();
		test.writeLock.unlock();
		test.readLock.unlock();
		test.readLock.unlock();
		test.readLock.unlock();

		test.test();

	}

	public void test() {
		for (int i = 0; i < 10; i++) {
			new Thread(new reader(this)).start();
		}
		for (int i = 0; i < 3; i++) {
			new Thread(new writer(this)).start();
		}
	}

	public void read() {
		readLock.lock();
		try {
			if (dataMap.isEmpty()) {
				Calendar now = Calendar.getInstance();
				System.out.println("线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "读取数据,但是dataMap为空");
			}
			String value = dataMap.get(index);
			Calendar now = Calendar.getInstance();
			System.out.println("线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "读取数据,key=" + index + ",value=" + value + ",dataMap大小为" + dataMap.size());
			if (value != null) {
				index++;
			}
		} finally {
			readLock.unlock();
		}
		try {
			Thread.sleep(3000);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void write() {
		writeLock.lock();
		try {
			String value = "value" + key;
			dataMap.put(new Integer(key), value);
			Calendar now = Calendar.getInstance();
			System.out.println("线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "写入数据,key=" + key + ",value=" + value + ",dataMap大小为" + dataMap.size());
			key++;
			try {
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} finally {
			writeLock.unlock();
		}
	}

	class reader implements Runnable {
		private ReadWriteLockDemo test = null;

		public reader(ReadWriteLockDemo test) {
			this.test = test;
		}

		@Override
		public void run() {
			Calendar now = Calendar.getInstance();
			System.out.println("读取线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "开始执行");
			for (int i = 0; i < 10; i++) {
				test.read();
			}
		}
	}

	class writer implements Runnable {
		private ReadWriteLockDemo test = null;

		public writer(ReadWriteLockDemo test) {
			this.test = test;
		}

		@Override
		public void run() {
			Calendar now = Calendar.getInstance();
			System.out.println("写入线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "开始执行");
			for (int i = 0; i < 10; i++) {
				test.write();
			}
		}
	}
}


    线程main第一次获取写入锁
    线程main第二次获取写入锁
    线程main第一次获取读取锁
    线程main第二次获取读取锁
    线程main第三次获取读取锁
    读取线程Thread-2在1302257210194开始执行
    线程Thread-2在1302257210194读取数据,但是dataMap为空
    线程Thread-2在1302257210194读取数据,key=100,value=null,dataMap大小为0
    写入线程Thread-12在1302257210194开始执行
    写入线程Thread-11在1302257210194开始执行
    线程Thread-12在1302257210195写入数据,key=100,value=value100,dataMap大小为1
    读取线程Thread-4在1302257210195开始执行
    读取线程Thread-6在1302257210195开始执行
    读取线程Thread-8在1302257210195开始执行
    读取线程Thread-3在1302257210195开始执行
    读取线程Thread-1在1302257210195开始执行
    读取线程Thread-5在1302257210195开始执行
    读取线程Thread-7在1302257210195开始执行
    读取线程Thread-0在1302257210195开始执行
    读取线程Thread-9在1302257210195开始执行
    写入线程Thread-10在1302257210195开始执行
    线程Thread-11在1302257210695写入数据,key=101,value=value101,dataMap大小为2
    线程Thread-4在1302257211215读取数据,key=100,value=value100,dataMap大小为2
    线程Thread-6在1302257211215读取数据,key=101,value=value101,dataMap大小为2
    线程Thread-8在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-1在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-3在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-5在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-7在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-0在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-9在1302257211215读取数据,key=102,value=null,dataMap大小为2
    线程Thread-10在1302257211216写入数据,key=102,value=value102,dataMap大小为3
    线程Thread-12在1302257211743写入数据,key=103,value=value103,dataMap大小为4
    线程Thread-11在1302257212243写入数据,key=104,value=value104,dataMap大小为5
    线程Thread-10在1302257212743写入数据,key=105,value=value105,dataMap大小为6
    线程Thread-12在1302257213243写入数据,key=106,value=value106,dataMap大小为7
    线程Thread-11在1302257213744写入数据,key=107,value=value107,dataMap大小为8
    线程Thread-2在1302257214244读取数据,key=102,value=value102,dataMap大小为8
    线程Thread-10在1302257214244写入数据,key=108,value=value108,dataMap大小为9
    线程Thread-12在1302257214744写入数据,key=109,value=value109,dataMap大小为10
    线程Thread-1在1302257215244读取数据,key=103,value=value103,dataMap大小为10
    线程Thread-3在1302257215244读取数据,key=104,value=value104,dataMap大小为10
    线程Thread-5在1302257215244读取数据,key=105,value=value105,dataMap大小为10
    线程Thread-7在1302257215244读取数据,key=106,value=value106,dataMap大小为10
    线程Thread-4在1302257215244读取数据,key=106,value=value106,dataMap大小为10
    线程Thread-6在1302257215244读取数据,key=107,value=value107,dataMap大小为10
    线程Thread-8在1302257215244读取数据,key=108,value=value108,dataMap大小为10
    线程Thread-9在1302257215244读取数据,key=110,value=value109,dataMap大小为10
    线程Thread-0在1302257215244读取数据,key=111,value=null,dataMap大小为10
    线程Thread-11在1302257215245写入数据,key=110,value=value110,dataMap大小为11
    线程Thread-10在1302257215745写入数据,key=111,value=value111,dataMap大小为12
    线程Thread-12在1302257216245写入数据,key=112,value=value112,dataMap大小为13
    线程Thread-11在1302257216745写入数据,key=113,value=value113,dataMap大小为14
    线程Thread-10在1302257217245写入数据,key=114,value=value114,dataMap大小为15
    线程Thread-12在1302257217745写入数据,key=115,value=value115,dataMap大小为16
    线程Thread-2在1302257218245读取数据,key=111,value=value111,dataMap大小为16
    线程Thread-11在1302257218245写入数据,key=116,value=value116,dataMap大小为17
    线程Thread-10在1302257218745写入数据,key=117,value=value117,dataMap大小为18
    线程Thread-4在1302257219245读取数据,key=112,value=value112,dataMap大小为18
    线程Thread-8在1302257219245读取数据,key=112,value=value112,dataMap大小为18
    线程Thread-6在1302257219245读取数据,key=113,value=value112,dataMap大小为18
    线程Thread-1在1302257219245读取数据,key=115,value=value115,dataMap大小为18
    线程Thread-3在1302257219245读取数据,key=115,value=value115,dataMap大小为18
    线程Thread-5在1302257219245读取数据,key=117,value=value116,dataMap大小为18
    线程Thread-7在1302257219245读取数据,key=117,value=value117,dataMap大小为18
    线程Thread-9在1302257219245读取数据,key=119,value=null,dataMap大小为18
    线程Thread-0在1302257219245读取数据,key=119,value=null,dataMap大小为18
    线程Thread-12在1302257219246写入数据,key=118,value=value118,dataMap大小为19
    线程Thread-11在1302257219746写入数据,key=119,value=value119,dataMap大小为20
    线程Thread-10在1302257220246写入数据,key=120,value=value120,dataMap大小为21
    线程Thread-12在1302257220746写入数据,key=121,value=value121,dataMap大小为22
    线程Thread-11在1302257221246写入数据,key=122,value=value122,dataMap大小为23
    线程Thread-10在1302257221746写入数据,key=123,value=value123,dataMap大小为24
    线程Thread-2在1302257222246读取数据,key=119,value=value119,dataMap大小为24
    线程Thread-12在1302257222246写入数据,key=124,value=value124,dataMap大小为25
    线程Thread-11在1302257222746写入数据,key=125,value=value125,dataMap大小为26
    线程Thread-3在1302257223247读取数据,key=120,value=value120,dataMap大小为26
    线程Thread-7在1302257223247读取数据,key=121,value=value121,dataMap大小为26
    线程Thread-1在1302257223247读取数据,key=122,value=value122,dataMap大小为26
    线程Thread-5在1302257223247读取数据,key=123,value=value123,dataMap大小为26
    线程Thread-9在1302257223247读取数据,key=124,value=value124,dataMap大小为26
    线程Thread-4在1302257223247读取数据,key=124,value=value124,dataMap大小为26
    线程Thread-8在1302257223247读取数据,key=126,value=value125,dataMap大小为26
    线程Thread-6在1302257223247读取数据,key=127,value=null,dataMap大小为26
    线程Thread-0在1302257223247读取数据,key=127,value=null,dataMap大小为26
    线程Thread-10在1302257223248写入数据,key=126,value=value126,dataMap大小为27
    线程Thread-12在1302257223748写入数据,key=127,value=value127,dataMap大小为28
    线程Thread-11在1302257224288写入数据,key=128,value=value128,dataMap大小为29
    线程Thread-10在1302257224788写入数据,key=129,value=value129,dataMap大小为30
    线程Thread-2在1302257225288读取数据,key=127,value=value127,dataMap大小为30
    线程Thread-3在1302257226247读取数据,key=128,value=value128,dataMap大小为30
    线程Thread-7在1302257226247读取数据,key=129,value=value129,dataMap大小为30
    线程Thread-1在1302257226247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-5在1302257226247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-9在1302257226247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-8在1302257226247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-4在1302257226247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-6在1302257226247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-0在1302257226248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-2在1302257228288读取数据,key=130,value=null,dataMap大小为30
    线程Thread-3在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-7在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-1在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-8在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-4在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-5在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-9在1302257229247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-6在1302257229248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-0在1302257229248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-2在1302257231288读取数据,key=130,value=null,dataMap大小为30
    线程Thread-3在1302257232247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-7在1302257232247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-1在1302257232247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-5在1302257232247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-9在1302257232247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-8在1302257232247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-4在1302257232248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-6在1302257232248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-0在1302257232248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-2在1302257234288读取数据,key=130,value=null,dataMap大小为30
    线程Thread-3在1302257235247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-8在1302257235247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-7在1302257235247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-1在1302257235247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-5在1302257235247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-9在1302257235247读取数据,key=130,value=null,dataMap大小为30
    线程Thread-4在1302257235248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-6在1302257235248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-0在1302257235248读取数据,key=130,value=null,dataMap大小为30
    线程Thread-2在1302257237289读取数据,key=130,value=null,dataMap大小为30
    线程Thread-8在1302257238261读取数据,key=130,value=null,dataMap大小为30
    线程Thread-6在1302257238261读取数据,key=130,value=null,dataMap大小为30
    线程Thread-0在1302257238261读取数据,key=130,value=null,dataMap大小为30
    线程Thread-4在1302257238261读取数据,key=130,value=null,dataMap大小为30
    线程Thread-3在1302257238268读取数据,key=130,value=null,dataMap大小为30
    线程Thread-7在1302257238268读取数据,key=130,value=null,dataMap大小为30
    线程Thread-1在1302257238268读取数据,key=130,value=null,dataMap大小为30
    线程Thread-5在1302257238268读取数据,key=130,value=null,dataMap大小为30
    线程Thread-9在1302257238268读取数据,key=130,value=null,dataMap大小为30
    线程Thread-2在1302257240307读取数据,key=130,value=null,dataMap大小为30
    线程Thread-8在1302257241279读取数据,key=130,value=null,dataMap大小为30
    线程Thread-6在1302257241279读取数据,key=130,value=null,dataMap大小为30
    线程Thread-0在1302257241279读取数据,key=130,value=null,dataMap大小为30
    线程Thread-4在1302257241279读取数据,key=130,value=null,dataMap大小为30
    线程Thread-3在1302257241291读取数据,key=130,value=null,dataMap大小为30
    线程Thread-7在1302257241291读取数据,key=130,value=null,dataMap大小为30
    线程Thread-1在1302257241291读取数据,key=130,value=null,dataMap大小为30
    线程Thread-5在1302257241291读取数据,key=130,value=null,dataMap大小为30
    线程Thread-9在1302257241291读取数据,key=130,value=null,dataMap大小为30


分享到:
评论

相关推荐

    通过多线程编程在Java中发现的并发模式和特性——线程、锁、原子等.zip

    在Java编程中,多线程是处理并发执行的关键技术,它允许程序同时执行多个任务,提高了系统的效率和响应性。本资料主要探讨了Java中的并发模式和特性,涉及线程、锁以及原子操作等概念。 1. **线程**: - **创建...

    Java多线程运算集合

    - Java多线程编程涉及多个方面的知识和技术,从基本的线程创建到高级的同步机制,都是开发高效、可靠的多线程应用程序所必需的。 - 正确理解和使用这些技术对于提高程序性能、避免死锁等问题至关重要。

    Java 多线程与并发(3-26)-Java 并发 - Java中所有的锁.pdf

    Java并发编程中,锁是一种关键机制,用于控制多个线程对共享资源的访问。本文主要探讨了Java中的两种广义锁概念——乐观锁和悲观锁,以及自旋锁和适应性自旋锁的区别和应用场景。 1. 乐观锁与悲观锁: 乐观锁认为在...

    java多线程学习笔记02(csdn)————程序.pdf

    Java多线程编程是开发高并发应用的关键技术之一。在这个学习笔记中,主要讨论了Java中的线程同步机制,包括volatile关键字、synchronized以及Lock接口,特别是ReentrantLock的使用。 首先,对于线程1和线程2的疑惑...

    23 按需上锁—ReadWriteLock详解.pdf

    《Java并发编程学习宝典(漫画版)》中提到的23章主要讲解了Java并发编程中的一个重要概念——ReadWriteLock,即读写锁。ReadWriteLock是`java.util.concurrent.locks`包下的一个接口,它是对传统互斥锁的一个扩展,...

    高级JAVA面试——最全的总结

    - 多线程:理解线程的创建、同步、并发控制,如synchronized、wait()、notify()等。 - 反射:了解反射机制,如何动态调用类、方法和字段。 2. **JAVA集合框架** - List、Set、Queue接口及其实现类:ArrayList、...

    8、读写锁ReentrantReadWriteLock&StampLock详解.pdf

    根据提供的文件信息,本文将详细解析读写锁`ReentrantReadWriteLock`以及`StampLock`在Java并发编程中的应用场景及其实现原理。 ### 一、读写锁介绍 #### 1.1 读写锁的基本概念 读写锁是一种特殊的锁机制,它可以...

    Java_Concurrency_in_Practice

    ### Java并发实践——深入理解多线程编程 #### 一、引言 《Java Concurrency in Practice》是一本由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes以及Doug Lea共同编写的经典之作。本书...

    笔记-4、显式锁和AQS1

    在Java并发编程中,显式锁(Lock)和隐式锁(synchronized)是两种常见的锁机制,它们提供了对共享资源的互斥访问。显式锁通过Java的Lock接口实现,而隐式锁主要依赖于synchronized关键字。 **Lock接口和...

    java并发编程源码-JCPCMF:Java并发编程核心方法和框架Maven源代码

    《Java并发编程源码解析——基于JCPCMF与Maven》 在Java编程领域,并发编程是一项关键的技术,它能够充分利用多核处理器的计算能力,提高应用程序的性能和响应速度。"Java并发编程源码-JCPCMF:Java并发编程核心方法...

    读者写者问题java源代码

    Java作为一种多线程编程语言,提供了丰富的API来解决这类问题。在Java中,我们可以利用`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法以及`ReentrantReadWriteLock`等工具来实现读者写者问题的解决...

    Concurrent+Programming+in+Java+-+Design+Principles+and+Patterns,+Second+Edition_

    ### 并发编程在Java中的设计原则与模式(第二版) #### 一、并发对象导向编程 本章节作为本书的开篇,旨在介绍如何在Java编程语言中思考、设计和实现并发程序。大部分内容假设读者已经是一位有经验的对象导向编程...

    多核与并发数据结构-用于列车售票的可线性化并发数据结构.zip

    Python虽然在多线程方面相对较弱,但可以通过GIL(全局解释器锁)和其他并发模型,如进程池和异步IO,实现并发操作。 在列车售票系统的并发数据结构设计中,可能会用到以下几种常见数据结构: 1. **队列**:用于...

    javaSE代码实例

    16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 348 16.2 线程的状态 350 16.3 线程的调度 351 16.3.1 睡眠 351 ...

Global site tag (gtag.js) - Google Analytics