并发编程:线程同步基础:7、StampedLock DEMO

目录

1、主程序

2、使用到的model类


1、主程序

java 复制代码
package xyz.jangle.thread.test.n2_7.stampedlock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.StampedLock;


/**
 * 
 * StampedLock	DEMO 
 * 	
 * 
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年7月26日 下午6:17:24
 * 
 */
public class M {

	public static void main(String[] args) {
		StampedLock lock = new StampedLock();
		Position p = new Position(1, 2);
		cWriter(p, lock).start();
		cReader(p, lock).start();
		cOptimisticReader(p, lock).start();

	}

	/**
	 *  创建写线程,该线程使用了StampedLock的写锁
	 *  使用 writeLock() 方法获取写锁
	 *  使用 unlockWrite(stamp) 方法释放写锁
	 * 
	 * @author jangle
	 * @time 2020年8月2日 下午2:59:41
	 * @param p
	 * @param lock
	 * @return
	 */
	public static Thread cWriter(Position p, StampedLock lock) {
		return new Thread(() -> {
			for (int i = 0; i < 2; i++) {
				System.out.println("开始获取写锁...");
				long stamp = lock.writeLock();
				try {

					System.out.println("开始进行写操作x:" + p.getX() + ",y:" + p.getY());
					p.setX(p.getX() + 1);
					p.setY(p.getY() + 1);
					System.out.println("完成写操作x:" + p.getX() + ",y:" + p.getY() + "开始停顿5秒");
					TimeUnit.SECONDS.sleep(5L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					lock.unlockWrite(stamp);
					System.out.println("释放写锁w stamp:" + stamp);
				}
				try {
					System.out.println("写线程无锁sleep 5秒");
					TimeUnit.SECONDS.sleep(5L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * 	创建读线程,该线程使用了StampedLock读锁
	 * 	使用 readLock() 方法获取读锁
	 * 	使用 unlockRead() 方法释放读锁
	 * @author jangle
	 * @time 2020年8月2日 下午3:00:21
	 * @param p
	 * @param lock
	 * @return
	 */
	public static Thread cReader(Position p, StampedLock lock) {
		return new Thread(() -> {
			for (int i = 0; i < 50; i++) {
				System.out.println("开始获取读锁");
				long stamp = lock.readLock();
				try {
					System.out.println("成功获得读锁:x:" + p.getX() + ",y:" + p.getY());
					TimeUnit.MILLISECONDS.sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					lock.unlockRead(stamp);
					System.out.println("完成读锁释放r stamp:" + stamp);
				}
			}
		});
	}

	/**
	 * 	创建乐观读线程,该线程使用了StampedLock的乐观读锁
	 * 	主要使用 tryOptimisticRead() 方法获取票据值stamp。
	 * 	通过票据值调用 validate(stamp) 方法求的当前值是否可用(是否被写锁占用)
	 * 
	 * @author jangle
	 * @time 2020年8月2日 下午3:03:30
	 * @param p
	 * @param lock
	 * @return
	 */
	public static Thread cOptimisticReader(Position p, StampedLock lock) {
		return new Thread(() -> {
			long stamp;
			for (int i = 0; i < 100; i++) {
				try {
					//
					stamp = lock.tryOptimisticRead();
					Integer x = p.getX();
					Integer y = p.getY();
					if (lock.validate(stamp)) {
						System.out.println("乐观读:x:" + x + ",y:" + y);
					} else {
						System.out.println("OptimisticReader:" + stamp + " Not Free x:" + x + ",y:" + y);
					}
					TimeUnit.MILLISECONDS.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	/**
	 * 	其他方法说明
	 * 
	 * @author jangle
	 * @time 2020年8月2日 下午3:25:28
	 * @param lock
	 */
	public static void other(StampedLock lock) {
		// 尝试获取读锁,未获取返回0
		long stampR = lock.tryReadLock();
//		lock.tryReadLock(time, unit);
		
		// 尝试获取写锁,未获取返回0
		long stampW = lock.tryWriteLock();
//		lock.tryWriteLock(time, unit);
		
		// 尝试将读锁转换为写锁,失败返回0
		long newStampW = lock.tryConvertToWriteLock(stampR);
		// 尝试将写锁转换为读锁,失败返回0
		long newStampR = lock.tryConvertToReadLock(stampW);
		// 尝试转换为乐观读锁,失败返回0,成功则可使用这个stamp进行验证
		long optStampR = lock.tryConvertToOptimisticRead(stampR);
		// 验证获取乐观读stamp之后,到目前位置,操作的共享数据是否可用。
		boolean validate = lock.validate(optStampR);
		if(validate) {
			// 可用,进行相关操作
		}else {
			// 不可用, 进行其他操作
		}
		
		// 判断当前是读锁还是写锁
		lock.isReadLocked();
		lock.isWriteLocked();
		
		// 释放对应的锁
		lock.unlock(stampR);
		lock.unlock(stampW);
		lock.unlock(newStampR);
		lock.unlock(newStampW);
	}
}

2、使用到的model类

java 复制代码
package xyz.jangle.thread.test.n2_7.stampedlock;

/**
 * 	StampedLock 的DEMO所要使用的共享数据类
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月2日 下午1:55:09
 * 
 */
public class Position {

	private Integer x, y;

	public Integer getX() {
		return x;
	}

	public void setX(Integer x) {
		this.x = x;
	}

	public Integer getY() {
		return y;
	}

	public void setY(Integer y) {
		this.y = y;
	}

	public Position(Integer x, Integer y) {
		super();
		this.x = x;
		this.y = y;
	}

}
相关推荐
鱟鲥鳚7 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
-银雾鸢尾-7 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-8 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白9 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地10 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
段一凡-华北理工大学11 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
Ljwuhe11 小时前
C++——多态
开发语言·c++
心平气和量大福大12 小时前
C#-WPF-Window主窗体
开发语言·c#·wpf
莫逸风13 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope