东方云开_Everglow 2016-12-07 09:21 采纳率: 0%
浏览 911
已结题

java C/S socket通信多线程问题

问题如下:客户端起十个线程,每个线程向服务端发一万次信息,服务端起五个线程,分别接收客户端的请求,每收到一次信息,数据库里把请求次数加一。执行完成后,验证一下数据库里请求次数是否为十万次.使用了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?"连接成功":"连接失败");
}
}

  • 写回答

2条回答 默认 最新

  • 吐泡泡丶 2016-12-07 09:47
    关注

    既然已经收到了10w个信息,那就是存数据的问题了,会不会是并发导致的

    评论

报告相同问题?

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图2.0 版本点聚合中Marker的位置无法实时更新,如何解决呢?
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题