并发编程:线程同步基础: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;
	}

}
相关推荐
人活一口气25 分钟前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP2 小时前
Vibe Coding -- 完整项目案例实操
java
荣码2 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing2 小时前
Google第三方授权登录
java·后端·程序员
明月光8182 小时前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑11 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯12 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路16 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还19 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev21 小时前
GreenDAO → Room
android·java·kotlin