Redis-jedis模拟多线程购票

前言: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状态(时间一定要足够让所有线程执行完毕)

posted @ 2019-05-26 22:12  茁壮成长的菜鸡  阅读(439)  评论(0编辑  收藏  举报