课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
Redis数据库的学习与应用在许多软件编程开发项目中都是会经常见到的一个数据库,而本文我们就通过案例分析来简单了解一下,Redis数据库应用方法分享。
1、多线程
将wait()、notifyAll()归为到多线程的方法中略有一些不恰当,这两个方法是Object中的方法。
①当调用了wait()方法后,让当前线程进入等待状态,并且让当前线程释放对象锁,等待既为阻塞状态,等待notifyAll()方法的唤醒。
wait()方法和sleep()方法有一些相似之处,都是使当前线程阻塞,但他们实际是有一些区别的。
执行wait()方法之前需要请求锁,wait()方法执行的时候会释放锁,等待被唤醒的时候竞争锁。
sleep()只是让当前线程休眠一段时间,无视锁的存在。
wait()是Object类的方法sleep()是Thread的静态方法
②notifyAll()方法为唤醒wait()中的线程。
notifyAll()和notify()方法都是可以唤醒调用了wait()方法,而陷入阻塞的线程。
但是notify()是随机唤醒这个阻塞队列中随机的一个线程,而notifyAll()是唤醒所用的调用了wait()方法而陷入阻塞的线程,让他们自己去抢占对象锁。
notifyAll()和notify()也都是必须在加锁的同步代码块中被调用,它们起的是唤醒的作用,不是释放锁的作用,只用在当前同步代码块中的程序执行完,也就是对象锁自然释放了,notifyAll()和notify()方法才会起作用,去唤醒线程。
wait()方法一般是和notify()或者notifyAll()方法一起连用的。
以上为掌握本篇博客必备的多线程知识,如果系统学习多线程的相关知识可查阅博客程序员田同学
2、Redis
加锁的过程本质上就是往Redis中set值,当别的进程也来set值时候,发现里面已经有值了,就只能放弃获取稍后再试。
Redis提供了一个天然实现锁机制的方法。
如果我们的业务中加了事务,该方法会返回null,不知道这是一个bug还是什么,这是Redis的一个巨坑,浪费了很长时间才发现了这个问题,如果解决此问题可以跳转到四章。
3、实现原理
分布式锁本质上要实现的目标就是在Redis里面占一个位置,当别的进程也要来占时,发现已经有人占在那里了,就只好放弃或者稍后再试。占位一般是使用setnx(setifnotexists)指令,只允许被一个客户端占位。先来先占,事办完了,再调用del指令释放茅坑。
其中,发现Redis中已经有值了,当前线程是直接放弃还是稍后再试分别就代表着,非阻塞锁和阻塞锁。
在我们的业务场景中肯定是要稍后再试(阻塞锁),如果是直接放弃(非阻塞锁)在数据库层面就可以直接做,就不需要我们在代码大费周章了。
非阻塞锁只能保存数据的正确性,在高并发的情况下会抛出大量的异常,当一百个并发请求到来时,只有一个请求成功,其他均会抛出异常。
Redis非阻塞锁和MySQL的乐观锁,终达到的效果是一样的,乐观锁是采用CAS的思想。
乐观锁方法:表字段加一个版本号,或者别的字段也可以!加版本号,可以知道控制顺序而已!在update的时候可以where后面加上version=oldVersion。数据库,在任何并发的情况下,update成功就是1失败就是0.可以根据返回的1,0做相应的处理!
我们更推荐大家使用阻塞锁的方式。
当获取不到锁时候,我们让当前线程使用wait()方法唤醒,当持有锁的线程使用完成后,调用notifyAll()唤醒所有等待的方法。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。