天天看点

java 线程重入锁:ReentrantLock 简单案例

在这就简单说下锁重要性吧,锁一般应用在安全方面。如项目中与钱相关的操作,单机情况下是基本没安全方面的问题。像网站这种,情况一:线程不安全,当多个请求同时到达,他们可能同时执行,我们的普通限制可能会失效,取款金额就可能出现负数(这一般是不允许出现的情况)。情况一:线程安全,我这指的是加锁,当多个请求同时到达,这样就能达到一条一条请求执行的效果。

案例(有锁的)

包:com.gx.mi_dome

三个类:     Jfdh_thread_lock( 锁的实现) 、Jfdh_thread(线程同步锁 继承Thread线程 ) 、 zhixing(主方法函数)

zhixing.java代码

package com.gx.mi_dome;
import com.gx.mi_dome.Jfdh_thread;
import com.gx.mi_dome.Jfdh_thread_lock;

public class zhixing {
	public static void main(String[] args) {
		Jfdh_thread_lock zhanghuone=new Jfdh_thread_lock(1000);//定义     用户拥有1000积分
		//第二种:循环
		int BB=1;
		int A_CS=13;
	
		for(int a=0;a< BB;a++){
			BB++;
			if(zhanghuone.getDhjf() < A_CS){//当前剩余积分 小于 当前所兑换积分
				System.out.println("兑换物品积分大于剩余积分");
				break;//结束循环    小智
			}
			
			Jfdh_thread takeMoney4=new Jfdh_thread(zhanghuone, A_CS);//建立线程对象  执行兑换积分方法
			A_CS=A_CS+3;//每次兑换积分加3
//			Jfdh_thread takeMoney2=new Jfdh_thread(zhanghuone, B_CS);//takeMoney2.start();
			takeMoney4.start();//start 开始
				//等待线程完成 	// 线程休眠1000ms(一秒)
				try {Thread.sleep(500);} catch (InterruptedException e) {//补捉     中断故障异常
					System.out.println("中断故障异常");
				}

		}		
		System.out.println("当前剩余积分:"+zhanghuone.getDhjf());
	}
	
}
           

Jfdh_thread_lock.java代码

package com.gx.mi_dome;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 
 * 锁的实现(ReentrantLock 重入锁)
 * 
 * @author 星月
 *
 */
public class Jfdh_thread_lock {
	
	/*
	 * 重入锁(ReentrantLock)是一种递归无阻塞的同步机制。以前一直认为它是synchronized的简单替代,
	 * 而且实现机制也相差太远。不过最近实践过程中发现它们之间还是有着天壤之别。
	 * 它提供了lock()方法:如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
	 * 如果当前线程已经保持该锁定,则将保持计数加 1,并且该方法立即返回。
	 * 如果该锁定被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁定之前,
	 * 该线程将一直处于休眠状态,此时锁定保持计数被设置为 1
	 */
     
//	ReentrantLock获取锁定与三种方式:
//	a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
//	b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
//	c) tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
//	d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断
	
//  Thread.setPriority(10); 就算设置线程优先等级 (最大:10  ,最小:1)  也不一定先执行  这涉及cpu工作原理	
	private final ReentrantLock lock=new ReentrantLock();//创建锁对象
	    
	/**
	 * 积分
	 */
	private Integer dhjf;
	
	public Integer getDhjf() {
		return dhjf;
	}

	public void setDhjf(Integer dhjf) {
		this.dhjf = dhjf;
	}

   //定义用户积分
	public Jfdh_thread_lock(Integer dhjf) {
		this.dhjf = dhjf;
	}//带参构造方法
	
	//方法函数    主要锁的代码块
	public  void jfdh_Method(Integer dhjf_CS) {
	
		lock.lock();// 加锁
		if (dhjf_CS <= this.dhjf) {
			// 模拟取积分成功
			System.out.println("兑换积分" + dhjf_CS + "分");
			// 线程暂停 10ms 模拟网络传输
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//  修改当前拥有积分
			this.dhjf = this.dhjf - dhjf_CS;
			System.out.println("剩余积分为:" + this.dhjf);
		} else {
			System.out.println("积分兑换失败");
		}
		lock.unlock();//解锁	
	}

}
           

Jfdh_thread.java代码

package com.gx.mi_dome;
import com.gx.mi_dome.Jfdh_thread_lock;
/**
 * 
 * 积分兑换线程同步锁 继承Thread线程
 * 
 * @author 星月
 *
 */
public class Jfdh_thread extends Thread{
	
	/**
	 * 积分线程锁对象
	 */
	private Jfdh_thread_lock jfdh_thread_lock;
	
	/**
	 * 积分
	 */
	private Integer dhjf;
	
	//AccountLock  同步锁
	public Jfdh_thread(Jfdh_thread_lock jfdh_thread_lock_CS,Integer dhjf_CS){
		this.jfdh_thread_lock=jfdh_thread_lock_CS;
		this.dhjf=dhjf_CS;
	}
	
	/**
	 * 模拟积分兑换方法
	 */
	@Override
	public void run() {
		jfdh_thread_lock.jfdh_Method(dhjf);
	}
	
}
           

自己写的一个案例,新手勿喷。