<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.AccountDao">
<update id="tranferin" parameterType="com.itheima.domin.tranfer">
update account set money=money+#{money} where aid=#{id}
</update>
<select id="count" resultType="int">
select count(*) from account
</select>
<select id="findName" resultType="int">
select name from user,account where uid=id
</select>
</mapper>
接口及类就不贴出来了
package com.itheima.Test;
import com.itheima.dao.AccountDao;
import com.itheima.dao.StundetDao;
import com.itheima.domin.tranfer;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
public class Tranfer implements Runnable{
public synchronized void run() {
while(true){
if(count<0||sum<16)
break;
for(int i=1;i<=16;i++){
//1.读取配置文件,生成字节输入流
try {
System.out.println("当前有"+count+"元 还剩 "+sum+" 个红包");
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(ExecutorType.BATCH, false);
//4.获取dao的代理对象
userDao = sqlSession.getMapper(AccountDao.class);
} catch (IOException e) {
e.printStackTrace();
}
Random random=new Random();
double rm=random.nextDouble();
rm=rm*10000;
tranfer tranfer=new tranfer();
tranfer.setId(i);
tranfer.setMoney(rm);
userDao.tranferin(tranfer);
sqlSession.commit();
sqlSession.close();
count=count-rm;
sum=sum-1;
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private volatile InputStream in;
private volatile SqlSession sqlSession;
private volatile AccountDao userDao;
/*红包总额总数*/
volatile static double count=1000000000;
/*红包数,尽量多*/
volatile static int sum=9000;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(ExecutorType.BATCH, false);
//4.获取dao的代理对象
userDao = sqlSession.getMapper(AccountDao.class);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
// sqlSession.commit();
//6.释放资源
sqlSession.commit();
sqlSession.close();
in.close();
}
public static void main(String args[]){
long timeStart=System.currentTimeMillis();
Tranfer tranfer=new Tranfer();
int i=1;
while(true){
/*使用4线程,修改4可改为其他*/
for(;i<=4;i++) {
new Thread(tranfer, "THREAD" + i).start();
System.out.println("执行了" + i + "线程");
}
if(count<0||sum<0)
break;
}
long timeend=System.currentTimeMillis();
System.out.println("结束时间为"+(timeend-timeStart));
}
}
使用12线程的测试结果 耗时49分钟
使用4线程 耗时41分种
由此可见线程数不是越多越好,现在对并发还缺少锁机制需进一步改进
下一步优化,使用mybatis的元素和不使用batch模式时候
测试类修改为
package com.itheima.Test;
import com.itheima.dao.AccountDao;
import com.itheima.dao.StundetDao;
import com.itheima.domin.tranfer;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Tranfer implements Runnable{
public synchronized void run() {
while(true){
if(count<0||sum<16)
break;
List<tranfer> tranfers=new ArrayList<tranfer>() ;
for(int i=1;i<=16;i++){
//1.读取配置文件,生成字节输入流
try {
System.out.println("当前有"+count+"元 还剩 "+sum+" 个红包");
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(true);
//4.获取dao的代理对象
userDao = sqlSession.getMapper(AccountDao.class);
} catch (IOException e) {
e.printStackTrace();
}
Random random=new Random();
double rm=random.nextDouble();
rm=rm*10000;
tranfer tranfer=new tranfer();
tranfer.setMoney(rm);
tranfer.setId(i);
tranfers.add(tranfer);
if(count>rm){
count=count-rm;
sum=sum-1;
}
}
System.out.println("提交信息");
if(sum<16)
break;
userDao.tranferin(tranfers);
sqlSession.commit();
sqlSession.close();
if(count<1000)
break;
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private volatile InputStream in;
private volatile SqlSession sqlSession;
private volatile AccountDao userDao;
volatile static double count=1000000000;
volatile static int sum=900000;
public static void main(String args[]){
long timeStart=System.currentTimeMillis();
Tranfer tranfer=new Tranfer();
int i=1;
while(true){
for(;i<=4;i++) {
new Thread(tranfer, "THREAD" + i).start();
System.out.println("执行了" + i + "线程");
}
if(count<1000||sum<0)
break;
}
long timeend=System.currentTimeMillis();
System.out.println("耗时:"+(timeend-timeStart));
}
}
"1.0" encoding="UTF-8"?>
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"com.itheima.dao.AccountDao">
运行时间缩短为29.2分钟,但仍需持续优化
尽量减少commit的次数如将代码实现commit的改为
while(true){
if(count<0||sum<16)
break;
List<tranfer> tranfers=new ArrayList<tranfer>() ;
for(int k=0;k<64;k++){
for(int i=1;i<=16;i++){
//1.读取配置文件,生成字节输入流
try {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(true);
//4.获取dao的代理对象
userDao = sqlSession.getMapper(AccountDao.class);
} catch (IOException e) {
e.printStackTrace();
}
Random random=new Random();
double rm=random.nextDouble();
rm=rm*10000;
tranfer tranfer=new tranfer();
tranfer.setMoney(rm);
tranfer.setId(i);
tranfers.add(tranfer);
if(count>rm){
count=count-rm;
sum=sum-1;
}
}
}
System.out.println("提交信息");
if(sum<16)
break;
userDao.tranferin(tranfers);
sqlSession.commit();
sqlSession.close();
System.out.println("当前有"+count+"元 还剩 "+sum+" 个红包");
if(count<1000)
break;
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}