Lock 锁的理解并附带简单实例

本文深入探讨了Java中的Lock接口和synchronized关键字的区别及应用。通过详细的代码示例展示了Lock的各种方法,包括lockInterruptibly、tryLock等,并对比了它们与synchronized的不同之处。
Lock 和 synchronized 都能实现锁机制。synchronized是java中的关键字,是系统内置的。关于synchronized,我前几天写了一篇个人心得。。。。。。。。
Lock 的源代码如下:
public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}
由此可见Lock是一个接口。
既然已经存在synchronized了,那为什么还要Lock呢?那就需要看下synchronized的特点了。


synchronized锁定对象了,除非异常或者程序执行结束,才会释放锁。如果中间的程序因为其它原因需要等待,其它线程必须等待。有时候我们希望一段时间还没有处理好,就要释放锁。在实际的开发过程中,我们更多的时候希望对锁进行更多的要求,例如尝试加锁,获取锁的状态,在等待锁时设置一个等待时间....


这些lock都能解决.




Lock比Synchronized对于锁有更多的功能。
Synchronized的使用,一般都是定义在方法体上或者定义在方法内部,直接synchronized(?){}。Synchronized不需要程序解锁,程序结束或者出现异常会自动解锁。
Lock有很大的不同,因为Lock是一个接口。我们需要new它的实现类ReentrantLock。Lock必须要手动解锁,为了防止死锁,解锁必须要放到finally体重。
例如


Lock lock = new ReentrantLock();
 lock.lock();
 try{
 // 需要执行的代码
 }catch(Excaption e){
 }finally{
  lock.unlock();
 }




下面通过代码,我全面的测试Lock的所有函数。


 1)lock()函数
public class Main {

 Lock lock = new ReentrantLock();

public static void main(String[] args) {
new TestThread().start();
new TestThread().start();
new TestThread().start();
}
public  void test(){


lock.lock();
try{
System.out.println(Thread.currentThread().getName() +"获取锁.....");
Thread.sleep(1000);
}catch(Exception e){

}finally{
System.out.println(Thread.currentThread().getName() +"释放锁.....");
lock.unlock();
}
}
}


class TestThread extends Thread{
@Override
public void run() {
new Main().test();
}
}


得到结果:
Thread-1获取锁.....
Thread-2获取锁.....
Thread-0获取锁.....
Thread-2释放锁.....
Thread-0释放锁.....
Thread-1释放锁.....


可见锁貌似没见效。下面我做个修改。
public class Main {


public static void main(String[] args) {

Lock lock = new ReentrantLock();
new TestThread(lock).start();
new TestThread(lock).start();
new TestThread(lock).start();
}
public  void test(Lock lock){


lock.lock();
try{
System.out.println(Thread.currentThread().getName() +"获取锁.....");
Thread.sleep(1000);
}catch(Exception e){

}finally{
System.out.println(Thread.currentThread().getName() +"释放锁.....");
lock.unlock();
}
}
}


class TestThread extends Thread{
Lock lock;

public TestThread(Lock lock) {
this.lock = lock;
}


@Override
public void run() {
new Main().test(lock);
}
}


执行结果:
Thread-0获取锁.....
Thread-0释放锁.....
Thread-1获取锁.....
Thread-1释放锁.....
Thread-2获取锁.....
Thread-2释放锁.....




可见生效了,其实很好理解。你要用同一把锁锁住才能满足需求。前者锁时成员变量,new的锁时对象私有的,每次new对象创建的是不同锁。




2)lockInterruptibly 函数 ,可以中断该线程


public class Main {

public static void main(String[] args) throws InterruptedException {

Lock lock = new ReentrantLock();
TestThread t1 = new TestThread(lock);
TestThread t2 = new TestThread(lock);
TestThread t3 = new TestThread(lock);

t1.start();t2.start();t3.start();

Thread.sleep(3000);
t2.interrupt();

}
public  void testInterruptibly(Lock lock) throws InterruptedException{


lock.lockInterruptibly();
try{
System.out.println(Thread.currentThread().getName() +"获取锁.....");
Thread.sleep(10000);
}finally{
System.out.println(Thread.currentThread().getName() +"释放锁.....");
lock.unlock();
}
}
}


class TestThread extends Thread{
Lock lock;

public TestThread(Lock lock) {
this.lock = lock;
}


@Override
public void run() {
try {
new Main().testInterruptibly(lock);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"  被中断了....");
}
}
}




运行结果:
Thread-0获取锁.....
Thread-1  被中断了....
Thread-0释放锁.....
Thread-2获取锁.....
Thread-2释放锁.....




可见线程1的确被中止了。




3)tryLock 函数,尝试获取锁,返回boolean,立即返回
public class Main {

public static void main(String[] args) throws InterruptedException {

Lock lock = new ReentrantLock();
TestThread t1 = new TestThread(lock);
TestThread t2 = new TestThread(lock);
TestThread t3 = new TestThread(lock);

t1.start();t2.start();t3.start();

}


public  void test(Lock lock){


lock.lock();
try{
System.out.println(Thread.currentThread().getName() +"获取锁.....");
Thread.sleep(1000);
}catch(Exception e){

}finally{
System.out.println(Thread.currentThread().getName() +"释放锁.....");
lock.unlock();
}
}
}


class TestThread extends Thread{
Lock lock;

public TestThread(Lock lock) {
this.lock = lock;
}


@Override
public void run() {
if(lock.tryLock()){
try{
new Main().test(lock);
}finally{
lock.unlock();
}
}
}
}
执行结果:
Thread-0获取锁.....
Thread-0释放锁.....


结果发现,的确生效了,另外两个线程执行时,没有获取到锁,所以直接结束了。


下面我做个简单的修改,将tryLock换成另外的tryLock,接下来我们说说tryLock(long time, TimeUnit unit) throws InterruptedException;
修改后的代码如下:
public class Main {

public static void main(String[] args) throws InterruptedException {

Lock lock = new ReentrantLock();
TestThread t1 = new TestThread(lock);
TestThread t2 = new TestThread(lock);
TestThread t3 = new TestThread(lock);

t1.start();t2.start();t3.start();

}


public  void test(Lock lock){


lock.lock();
try{
System.out.println(Thread.currentThread().getName() +"获取锁.....");
Thread.sleep(1000);
}catch(Exception e){

}finally{
System.out.println(Thread.currentThread().getName() +"释放锁.....");
lock.unlock();
}
}
}


class TestThread extends Thread{
Lock lock;

public TestThread(Lock lock) {
this.lock = lock;
}


@Override
public void run() {
try {
if(lock.tryLock(10, TimeUnit.SECONDS)){
try{
new Main().test(lock);
}finally{
lock.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}




执行结果:
Thread-1获取锁.....
Thread-1释放锁.....
Thread-2获取锁.....
Thread-2释放锁.....
Thread-0获取锁.....
Thread-0释放锁.....


在获取锁的时候,等待了10秒,这个时间后,锁的确已经释放了。下面我将test()方法中等待的时间设置超过等待的时间10秒。
public class Main {

public static void main(String[] args) throws InterruptedException {

Lock lock = new ReentrantLock();
TestThread t1 = new TestThread(lock);
TestThread t2 = new TestThread(lock);
TestThread t3 = new TestThread(lock);

t1.start();t2.start();t3.start();

}


public  void test(Lock lock){


lock.lock();
try{
System.out.println(Thread.currentThread().getName() +"获取锁.....");
Thread.sleep(15000);
}catch(Exception e){

}finally{
System.out.println(Thread.currentThread().getName() +"释放锁.....");
lock.unlock();
}
}
}


class TestThread extends Thread{
Lock lock;

public TestThread(Lock lock) {
this.lock = lock;
}


@Override
public void run() {
try {
if(lock.tryLock(10, TimeUnit.SECONDS)){
try{
new Main().test(lock);
}finally{
lock.unlock();
}
}else{
System.out.println(Thread.currentThread().getName()+"   等待超时...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果:
Thread-1获取锁.....
Thread-2   等待超时...
Thread-0   等待超时...
Thread-1释放锁.....




结果和预期的一致。


tryLock(...) 函数会尝试获取锁,如果拿不到锁,在没有设置等待时间的时候,会立即返回false。如果设置了等待时间,等待时间过去后,还是拿不到锁,会返回false,中端获取锁。




4) unlock() 函数,这个函数很简单,释放锁,只需要注意一个地方即可,代码必须放到finally中,确保不会因为程序异常导致死锁。


5) newCondition() 这个函数能实现object对象中的wait notify函数的功能。具体可以参考我同时写的另外一篇文章。

















内容概要:本文详细介绍了一种基于Simulink的表贴式永磁同步电机(SPMSM)有限控制集模型预测电流控制(FCS-MPCC)仿真系统。通过构建PMSM数学模型、坐标变换、MPC控制器、SVPWM调制等模块,实现了对电机定子电流的高精度跟踪控制,具备快速动态响应和低稳态误差的特点。文中提供了完整的仿真建模步骤、关键参数设置、核心MATLAB函数代码及仿真结果分析,涵盖转速、电流、转矩和三相电流波形,验证了MPC控制策略在动态性能、稳态精度和抗负载扰动方面的优越性,提出了参数自整定、加权代价函数、模型预测转矩控制和弱磁扩速等优化方向。; 适合人群:自动化、电气工程及其相关专业本科生、研究生,以及从事电机控制算法研究与仿真的工程技术人员;具备一定的电机原理、自动控制理论和Simulink仿真基础者更佳; 使用场景及目标:①用于永磁同步电机模型预测控制的教学演示、课程设计或毕业设计项目;②作为电机先进控制算法(如MPC、MPTC)的仿真验证平台;③支撑科研中对控制性能优化(如动态响应、抗干扰能力)的研究需求; 阅读建议:建议读者结合Simulink环境动手搭建模型,深入理解各模块间的信号流向与控制逻辑,重点掌握预测模型构建、代价函数设计与开关状态选择机制,可通过修改电机参数或控制策略进行拓展实验,以增强实践与创新能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值