实际工作中,经常会遇到多线程并发时的类似抢购的功能,本篇描述一个简单的redis分布式锁实现的多线程抢票功能。
直接上代码。首先按照慣例,給出一個错误的示范:
我们可以看看,当20个线程一起来抢10张票的时候,会发生什么事。
package com.tiger.utils;
public class TestMutilThread {
// 总票量
public static int count = 10;
public static void main(String[] args) {
statrtMulti();
}
public static void statrtMulti() {
for (int i = 1; i <= 20; i++) {
TicketRunnable tickrunner = new TicketRunnable();
Thread thread = new Thread(tickrunner, "Thread No: " + i);
thread.start();
}
}
public static class TicketRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " start "
+ count);
// TODO Auto-generated method stub
// logger.info(Thread.currentThread().getName()
// + " really start" + count);
if (count <= 0) {
System.out.println(Thread.currentThread().getName()
+ " ticket sold out ! No tickets remained!" + count);
return;
} else {
count = count - 1;
System.out.println(Thread.currentThread().getName()
+ " bought a ticket,now remaining :" + (count));
}
}
}
}
测试结果,从结果可以看到,票数在不同的线程中已经出现混乱。
Thread No: 2 start 10
Thread No: 6 start 10
Thread No: 4 start 10
Thread No: 5 start 10
Thread No: 3 start 10
Thread No: 9 start 6
Thread No: 1 start 10
Thread No: 1 bought a ticket,now remaining :3
Thread No: 9 bought a ticket,now remaining :4
Thread No: 3 bought a ticket,now remaining :5
Thread No: 12 start 3
Thread No: 5 bought a ticket,now remaining :6
Thread No: 4 bought a ticket,now remaining :7
Thread No: 8 start 7
Thread No: 7 start 8
Thread No: 12 bought a ticket,now remaining :1
Thread No: 14 start 0
Thread No: 6 bought a ticket,now remaining :8
Thread No: 16 start 0
Thread No: 2 bought a ticket,now remaining :9
Thread No: 16 ticket sold out ! No tickets remained!0
Thread No: 14 ticket sold out ! No tickets remained!0
Thread No: 1