前言:edis的key是单线程模式,这就意味一瞬间只有一个线程能够持有这个key,所以可以使用redis解决部分涉及线程安全的业务。例如:在模拟卖票的实验中,通过加锁的方式为线程上锁,保证每一个线程有一个锁。
回顾:
如何实现多线程?
答:常用两种方式实现多线程
1.继承Thread类,重写run方法,创建对象后,调用start()方法启动线程
2.实现Runnable接口,重写run方法,创建对象,调用start()方法启动线程(推荐使用)
测试代码结构图:
继承Runnable接口,重写run方法
package cn.lch.thread; import redis.clients.jedis.Jedis; @SuppressWarnings("all") public class TicketThread implements Runnable{ @Override public void run() { //创建一个连接实例 Jedis jedis = new Jedis("192.168.93.3",6379); //进行密码验证 String auth = jedis.auth("lch"); //拿到key为ticket_num的值并进行递减 Long decr = jedis.decr("ticket_num"); if(decr>=0) { System.out.println(Thread.currentThread().getName()+"抢票成功,票号:"+(decr+1)); }else { System.out.println(Thread.currentThread().getName()+"抢票失败"); } jedis.close(); } }
在redis数据库中插入一条key为ticket_num,值为10的数据
测试代码
package cn.lch.test; import java.util.HashSet; import cn.lch.thread.TicketThread; public class ThreadTest { //在多线程的情况下,尽量不要采用单元测试 public static void main(String[] args) { HashSet<Thread> hashSet = new HashSet<>(); for (int i = 0; i < 15; i++) { Thread thread = new Thread(new TicketThread()); thread.setName(i+"号"); hashSet.add(thread); } for (Thread aa : hashSet) { aa.start(); } } }
测试结果
注意事项:在多线程的demo中,尽量不要使用单元测试的方法,因为单元测试,测试多线程的时候,一旦单元测试的方法执行结束,就释放内存空间;这样有可能会导致还没有执行结束的线程,无法继续执行了,如果一定要采用单元测试的方法,应在方法最后加上一个阻塞线程的方法,例如另线程进入sleep状态(时间一定要足够让所有线程执行完毕)