问题如下:客户端起十个线程,每个线程向服务端发一万次信息,服务端起五个线程,分别接收客户端的请求,每收到一次信息,数据库里把请求次数加一。执行完成后,验证一下数据库里请求次数是否为十万次.使用了Mybatis框架来操作数据库,代码如下.
问题是:如果不加数据库操作,是可以完整收到10W个信息.但是如果加上数据库操作,就会少收到3000条左右的信息,问题在哪?怎么解决?或者用其他什么方法可以解决.
客户端:
package homework8;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
Socket clientSocket;
OutputStreamWriter outputStreamWriter ;
public static void main(String[] args) throws Exception{
new Client().connect();
}
class MyThread extends Thread {
public void run(){
int i;
for(i=0;i<10000;i++){
try{
System.out.println(Thread.currentThread().getName()+"执行第"+i+"次发送");
outputStreamWriter.write("哈哈"+"\r\n");
outputStreamWriter.flush();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
public void connect() throws Exception{
clientSocket =new Socket(InetAddress.getLocalHost(),8088);
outputStreamWriter=new OutputStreamWriter(clientSocket.getOutputStream());
for(int k=0;k<10;k++){
MyThread thread=new MyThread();
thread.start();
}
}
}
服务器:
package homework8;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.ibatis.session.SqlSession;
import util.MybatisUtil;
public class Server1 {
static Server1 server;
BufferedReader bufferedReader;
public int times;
public int i=1;
ServerThread st;
ServerSocket ss;
private static final int SERVER_PORT =8088;
//接收客户端请求 并启动线程
public void update(int k) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.update("requestNamespace.update",k);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public void receive() throws Exception{
ss=new ServerSocket(SERVER_PORT);
try {
while (true) {
Socket socket = ss.accept();
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
st=new ServerThread();
Thread thread1 = new Thread(st, "SyncThread1");
Thread thread2 = new Thread(st, "SyncThread2");
Thread thread3 = new Thread(st, "SyncThread3");
Thread thread4 = new Thread(st, "SyncThread4");
Thread thread5 = new Thread(st, "SyncThread5");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}catch (IOException e) {
}finally {
ss.close();
}
}
//创建线程的内部类
class ServerThread implements Runnable {
public void run() {
try {
String line="a";
while (!line.equals("qwerty")) {
synchronized (this) {
line=bufferedReader.readLine();
System.out.println(Thread.currentThread().getName()+"接收了第"+i+"个"+line);
i++;
update(i);
}
}
}catch (Exception e) {
e.printStackTrace();
System.out.println("接收完毕");
try{
ss.close();
}catch(Exception x){
x.printStackTrace();
}
}
}
}
//启动服务器
public static void main(String[] args)throws Exception {
server=new Server1();
server.receive();
}
}
Mybatis工具类
package util;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MybatisUtil {
private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
//加载mybatis配置文件
static{
try {
Reader reader=Resources.getResourceAsReader("mybatis.config.xml");
sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
//获取线程
public static SqlSession getSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
if(sqlSession == null){
//在SqlSessionFactory非空的情况下,获取SqlSession对象
sqlSession = sqlSessionFactory.openSession();
//将SqlSession对象与当前线程绑定在一起
threadLocal.set(sqlSession);
}
//返回SqlSession对象
return sqlSession;
}
//关闭SqlSession与当前线程分开
public static void closeSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//如果SqlSession对象非空
if(sqlSession != null){
//关闭SqlSession对象
sqlSession.close();
//分开当前线程与SqlSession对象的关系
threadLocal.remove();
}
}
public static void main(String[] args) {
Connection conn = MybatisUtil.getSqlSession().getConnection();
System.out.println(conn!=null?"连接成功":"连接失败");
}
}