Created
August 6, 2016 11:23
-
-
Save zhugw/0852f5f0ee38f07a8661d0e57db1853e to your computer and use it in GitHub Desktop.
多线程模拟并发抽奖中礼帽和兑奖
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zhugw; | |
import org.apache.commons.lang3.RandomStringUtils; | |
import java.sql.*; | |
import java.util.concurrent.CountDownLatch; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
/** | |
* Created by duanmu on 8/6/16. | |
*/ | |
public class ConcurrentUpdateTotalAmountTest { | |
public static final String url = "jdbc:mysql://localhost:3306/test"; | |
public static final String user = "root"; | |
public static final String password = "12345678"; | |
public static void main(String[] args) throws InterruptedException, SQLException { | |
int nThreads = 6; //6个线程 3个抽奖 3个兑奖 | |
ExecutorService pool = Executors.newFixedThreadPool(nThreads); | |
final CountDownLatch startLatch = new CountDownLatch(nThreads); | |
final CountDownLatch endLatch = new CountDownLatch(nThreads); | |
String mobile = RandomStringUtils.randomNumeric(11); | |
initData(mobile); //数据初始化 默认当前总礼帽为3 | |
// 模拟3个抽奖 每次都中了1个礼帽 total_amount+1 | |
for (int i = 0; i < 3; i++) { | |
pool.submit(() -> { | |
startLatch.countDown(); | |
try { startLatch.await(); } catch (Exception e1) { } //等待所有任务都提交了再往下执行 保证并发 | |
try { | |
Connection connection = DriverManager.getConnection(url, user, password); | |
connection.setAutoCommit(false); | |
Statement stat = connection.createStatement(); | |
// 添加中奖日志 | |
String insertSql = "insert into user_draw_log(mobile,amount) values('%s',1)"; | |
stat.execute(String.format(insertSql, mobile)); | |
// 更新总礼帽数 | |
String updateSql = "update user_draw_info set total_amount = total_amount+1 where mobile = '%s'"; | |
stat.executeUpdate(String.format(updateSql, mobile)); | |
System.out.printf("mobile: %s中小礼帽成功更新总礼帽数%n",mobile); | |
connection.commit(); | |
} catch (SQLException e) { | |
e.printStackTrace(); | |
}finally{ | |
endLatch.countDown(); | |
} | |
}); | |
} | |
// 模拟3个兑奖操作 total_amount=0 | |
for (int i = 0; i < 3; i++) { | |
pool.submit(() -> { | |
startLatch.countDown(); | |
try { startLatch.await(); } catch (Exception e1) { } //等待所有任务都提交了再往下执行 保证并发 | |
try { | |
Connection connection = DriverManager.getConnection(url, user, password); | |
connection.setAutoCommit(false); | |
Statement stat = connection.createStatement(); | |
// 先查询出累积礼帽 | |
String queryTotalAmountSql = "select total_amount from user_draw_info where mobile = '%s'"; | |
ResultSet resultSet = stat.executeQuery(String.format(queryTotalAmountSql, mobile)); | |
resultSet.next(); | |
int totalAmount = resultSet.getInt("total_amount"); | |
if(totalAmount>0) { // 若累积礼帽大于0 | |
// 礼帽清零 | |
String resetSql = "update user_draw_info set total_amount = 0 where mobile='%s' and total_amount=%d"; | |
int count = stat.executeUpdate(String.format(resetSql, mobile,totalAmount)); | |
if(count>0){ // 礼帽清零成功 | |
// 模拟发券 | |
String insertSql = "insert user_redeem_log (mobile,redeem_amount) values('%s',%d)"; | |
stat.execute(String.format(insertSql, mobile,totalAmount)); | |
System.out.printf("mobile: %s 成功兑券: %d%n",mobile,totalAmount); | |
}else{System.out.printf("mobile: %s 礼帽清零失败%n",mobile);} | |
} | |
connection.commit(); | |
} catch (SQLException e) { | |
e.printStackTrace(); | |
}finally{ | |
endLatch.countDown(); | |
} | |
}); | |
} | |
endLatch.await(); //等待所有的任务都完成 | |
System.out.println("Done"); | |
System.exit(0); | |
} | |
private static void initData(String mobile) throws SQLException { | |
Connection connection = DriverManager.getConnection(url, user, password); | |
Statement stat = connection.createStatement(); | |
String sql = "insert into user_draw_info(mobile,total_amount) values('%s',3)"; | |
stat.execute(String.format(sql, mobile)); | |
System.out.println("数据初始化完成"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment