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