Обработка больших объемов данных, получаемых через сокет TCP несколькими потоками Java

#java #multithreading #sockets

Вопрос:

У меня есть серверный сокер, каждую секунду клиент будет отправлять данные на сервер. Данные представляют собой строку, содержащую около 5000 строк, я хочу разделить эти данные на 5 частей для одновременной обработки 5 потоками.

 private void listening() {
        while (true) {
            try {
                clientSocket = serverSocket.accept();
                System.out.println(clientSocket.getInetAddress());
                BufferedReader os = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                new Thread(() -> {
                    try {
                        while (true) {
                            String data = os.readLine();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }).start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 

Вот пример кода, что я должен сделать, чтобы разделить данные на 5 частей?

Пример данных: NVL01_1,20210624045425,172.67.216.146,5027,227.1.50.52,8870,212.133.114.73,2017 NVL01_1,20210624045425,193.25.63.53,6313,216.243.18.239,4445,227.236.233.188,2528 NVL01_1,20210624045425,111.176.240.164,2254,53.3.85.55,3829,72.195.203.220,8903 NVL01_1,20210624045425,223.224.123.173,1596,237.81.112.22,5669,25.193.178.6,5719 NVL01_1,20210624045425,178.89.46.197,489,140.87.132.177,4772,154.172.63.136,3045 NVL01_1,20210624045425,25.201.145.226,3004,234.138.243.22,6831,107.122.249.80,9609 NVL01_1,20210624045425,94.163.66.108,6041,37.190.105.119,9280,89.212.205.137,7483 NVL01_1,20210624045425,90.119.3.94,8881,96.137.66.26,7281,1.99.109.175,9525 NVL01_1,20210624045425,106.116.39.233,1280,196.62.122.91,1649,60.112.241.253,6697 NVL01_1,20210624045425,179.187.138.181,3870,62.38.25.158,4272,74.152.247.34,5220 NVL01_1,20210624045425,204.11.249.30,4749,234.133.240.8,7808,105.193.120.29,9638 NVL01_1,20210624045425,2.99.210.82,6924,206.153.6.165,7520,81.157.119.248,7638 NVL01_1,20210624045425,84.205.46.70,4275,188.189.94.143,4304,172.70.59.8,1226 NVL01_1,20210624045425,38.133.52.221,9577,87.183.254.244,9694,230.209.104.133,164 NVL01_1,20210624045425,13.43.85.59,2894,10.190.222.113,2948,96.155.28.151,9891 NVL01_1,20210624045425,16.79.32.72,7628,57.163.233.173,1,138.67.131.44,5079 NVL01_1,20210624045425,99.123.115.184,5113,197.56.206.97,9480,222.162.213.230,9564 NVL01_1,20210624045425,133.126.151.28,7437,3.80.234.183,5566,235.50.191.69,744 NVL01_1,20210624045425,71.86.226.128,5212,163.29.130.8,6954,160.182.239.31,1622 NVL01_1,20210624045425,145.78.71.65,2124,197.135.78.117,340,247.187.243.124,6136 NVL01_1,20210624045425,145.208.217.4,9493,8.138.165.8,8975,11.13.156.146,6828 NVL01_1,20210624045425,46.23.207.136,5328,151.197.27.17,3823,253.221.4.92,7230 NVL01_1,20210624045425,189.204.114.107,6709,44.199.81.116,5490,178.66.79.37,1437 NVL01_1,20210624045425,114.48.39.253,9602,27.38.239.223,1566,224.207.76.203,1899 NVL01_1,20210624045425,42.55.138.38,4812,51.93.10.2,7836,95.189.159.240,9574 NVL01_1,20210624045425,141.24.136.19,422,248.144.61.220,2427,138.88.193.240,2284 NVL01_1,20210624045425,146.176.9.78,6852,198.41.131.88,1094,227.242.134.106,5715 NVL01_1,20210624045425,134.47.77.168,7825,90.1.25.81,9125,175.143.184.94,5291 NVL01_1,20210624045425,131.180.238.244,7408,20.87.233.210,592,148.178.232.143,2782 NVL01_1,20210624045425,127.144.113.136,1375,197.9.246.61,7113,181.163.124.51,4290 NVL01_1,20210624045425,131.204.107.100,7185,192.181.253.8,2237,207.147.69.181,4239 NVL01_1,20210624045425,123.28.117.19,5432,89.11.193.31,9282,34.193.75.180,8747 NVL01_1,20210624045425,96.24.44.203,9186,73.65.43.110,4013,174.193.2.241,8762 NVL01_1,20210624045425,164.248.38.5,3122,245.59.114.8,5506,231.212.210.94,8837 NVL01_1,20210624045425,144.86.166.14,8583,123.127.122.39,8625,6.132.112.158,1653 NVL01_1,20210624045425,195.6.162.254,3597,24.218.41.173,1357,24.55.15.35,921 NVL01_1,20210624045425,75.13.49.219,9779,9.202.212.168,2309,11.142.118.22,1955 NVL01_1,20210624045425,245.132.44.122,9659,12.116.75.191,7258,88.91.180.73,2457 NVL01_1,20210624045425,223.31.193.225,5257,194.245.37.73,4567,197.134.216.13,6327 NVL01_1,20210624045425,251.30.222.188,4178,106.83.17.52,4045,142.99.100.174,6164 NVL01_1,20210624045425,209.115.15.248,9416,124.213.26.22,128,145.6.19.210,2801 NVL01_1,20210624045425,189.174.30.164,7052,24.191.53.184,8172,20.57.226.30,8362 NVL01_1,20210624045425,235.148.200.174,5072,162.253.12.169,7542,205.85.11.196,553 NVL01_1,20210624045425,164.121.163.241,9549,60.225.45.42,7108,255.147.26.90,7637 NVL01_1,20210624045425,145.3.148.142,7128,76.29.166.83,6432,152.25.4.242,1605 NVL01_1,20210624045425,194.170.50.219,6973,229.63.113.168,5698,164.5.6.101,6650 NVL01_1,20210624045425,39.184.47.229,367,17.180.188.224,5841,70.42.225.241,6074 NVL01_1,20210624045425,36.62.110.27,2587,105.252.86.145,7262,57.63.203.247,4518 NVL01_1,20210624045425,225.173.252.217,4665,115.177.84.223,4614,62.203.148.102,7514 NVL01_1,20210624045425,146.128.170.11,2411,76.187.243.147,4396,224.224.170.32,4872 NVL01_1,20210624045425,27.209.151.174,4614,0.125.68.119,2427,39.208.125.100,940 NVL01_1,20210624045425,88.90.208.193,7722,35.102.255.5,3604,214.45.25.189,7213 NVL01_1,20210624045425,96.33.115.231,5202,128.192.0.70,4048,160.221.24.37,3806 NVL01_1,20210624045425,84.26.118.109,2940,109.36.178.60,3276,170.183.57.80,6159 NVL01_1,20210624045425,225.67.85.90,3034,73.62.181.134,291,97.92.65.165,6845 NVL01_1,20210624045425,160.177.222.98,5610,134.70.105.214,65,24.69.80.75,5193 NVL01_1,20210624045425,142.49.198.59,7820,176.83.196.180,2107,40.68.245.29,9761 NVL01_1,20210624045425,59.199.111.242,734,222.236.118.31,7964,210.83.178.184,4373 NVL01_1,20210624045425,115.106.166.229,5409,77.171.38.150,2611,4.217.213.148,9342 NVL01_1,20210624045425,18.54.5.157,9803,48.47.15.108,4348,224.211.21.208,6431 NVL01_1,20210624045425,135.21.210.96,3068,203.5.250.83,9397,221.89.166.128,3374 NVL01_1,20210624045425,191.223.45.133,9746,227.252.45.227,2955,105.233.104.84,4350 NVL01_1,20210624045425,113.39.211.171,2688,63.230.236.139,2083,213.155.51.185,1973 NVL01_1,20210624045425,92.242.126.24,7434,30.44.168.146,3950,177.251.17.214,7967 NVL01_1,20210624045425,194.134.48.232,8858,14.13.21.182,9196,236.92.11.13,9344 NVL01_1,20210624045425,130.3.48.196,9380,112.89.224.216,4645,157.199.7.200,1790 NVL01_1,20210624045425,229.36.230.48,8815,116.98.169.138,505,134.232.82.65,727 NVL01_1,20210624045425,67.133.95.171,7594,214.33.143.109,5649,71.73.166.217,3153 NVL01_1,20210624045425,225.153.10.77,5447,139.209.199.128,2845,71.108.112.231,4144 NVL01_1,20210624045425,108.253.199.77,3088,203.35.58.102,8689,138.78.85.194,7954 NVL01_1,20210624045425,48.242.189.77,49,56.20.207.122,9542,179.159.117.240,9634 NVL01_1,20210624045425,47.46.208.195,9766,145.154.85.14,2952,189.187.53.186,7724 NVL01_1,20210624045425,95.124.222.197,9549,227.219.232.255,4794,161.166.17.242,4141

Ответ №1:

Как насчет использования data.split (), а затем создания потока для каждого такого типа данных?

 //this will split the data in 5 where the text is marked by /'/
String[] splitdata = data.split("/'/", 5);
for(int i=0;i<5;i  )
    startThread(splitdata[5]);
 

называть

 public void startThread(String data){
    //starts the thread with the split data
}
 

вот пример:

 String data="...NVL01_...5719 /'/NVL01_...3045... etc."
String[] splitdata = data.split("/'/", 5);
System.out.println(splitdata[0]) //...NVL01_...5719
System.out.println(splitdata[1]) //...NVL01_...3045
etc.
 

вам просто нужно будет поставить какой-то знак там, где вы хотите, чтобы строка была разделена перед отправкой данных.

Комментарии:

1. как насчет того, чтобы строковые данные содержали 5000 строк?

2. В чем была бы проблема, если бы он содержал 5000 строк? вы хотите сказать, что вам нужен поток для каждой 1000 строк?

3. Верно. итак, первая задача-разделить эти данные на 5 частей

4. У вас есть три варианта: 1) поместите маркер, такой как/’/, где вы хотите, чтобы данные разделили его перед фактической отправкой (что я рекомендую, так как это намного проще), или 2) сделайте String[] lines = contents.split("\r?\n"); , и вы получите 5000 строк. вы передаете каждую 1000 в каждый поток или 3) создаете регулярное выражение, которое разбивает каждые 1000 строк, и используете его для разделения строки на 5 (я не знаю, как будет выглядеть регулярное выражение).

5. Я бы все равно рекомендовал поместить разделитель внутри данных перед их отправкой, так как это намного проще, чем два других варианта.

Ответ №2:

С помощью этого примера вы могли бы выполнить эту работу.

 public static String[] splitFive(String data) {
    int factor = 1;
    String [] parts = new String[5];
    if(data.length() >= 5){
        //
        factor = data.length() / 5;
        parts[0] = data.substring(0, factor);
        parts[1] = data.substring(factor, factor * 2);
        parts[2] = data.substring(factor*2, factor * 3);
        parts[3] = data.substring(factor*3, factor * 4);
        parts[4] = data.substring(factor*4);
    } else {
        for(int i = 0; i  <  data.length(); i  ){
            parts[i] = String.valueOf(data.charAt(i));
        }
    }
    return parts;
}

String [] result = splitFive("1234");
String [] result2 = splitFive("12345678901234567890--");
 

Будет возвращать:

 field String[] result = String[5] { "1", "2", "3", "4", null }
field String[] result2 = String[5] { "1234", "5678", "9012", "3456", "7890--" }
 

Отредактированный пример метода для работы со строками:

 public static List[] splitFive(String data) {
    List [] parts = new List [5];
    String [] allLines = data.split("n");
    int factor = 1;
    List<String> allLinesList = Arrays.asList(allLines);
    if(allLines.length >= 5){
        factor = allLines.length / 5;
        parts[0] = allLinesList.subList(0, factor);
        parts[1] = allLinesList.subList(factor, factor * 2);
        parts[2] = allLinesList.subList(factor*2, factor * 3);
        parts[3] = allLinesList.subList(factor*3, factor * 4);
        parts[4] = allLinesList.subList(factor*4, allLinesList.size());
    } else {
        for(int i = 0; i  < allLines.length ; i  ){
            parts[i] =  Collections.singletonList(allLinesList.get(i));
        }
    }
    return parts;
}


StringBuilder sb = new StringBuilder();
for(int i = 0; i <10; i  ){
    sb.append("Line-" i "n");
}

List [] result = splitFive("1234n4567n464646464654654n");
List [] result2 = splitFive(sb.toString());

 

Это вернется

 field List[] result = List[5] { [1234], [4567], [464646464654654], null, null }

field List[] result2 = List[5] { [Line-0, Line-1], [Line-2, Line-3], [Line-4, Line-5], [Line-6, Line-7], [Line-8, Line-9] }
 

Комментарии:

1. как насчет того, чтобы строковые данные содержали 5000 строк?

2. Вы сказали 5 частей, но если вы хотите работать с полными строками, то вам лучше использовать разделение, как указано в другом ответе.