Java 多线程多请求方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12835077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 10:24:21  来源:igfitidea点击:

Java Multithread Multiple Requests Approach

javamultithreadingconcurrencyhttp-post

提问by D.Snap

I want to send to "test.com" a request from 0 to 100, the code i have will send a request every one second... In this way the program will take 100 seconds in order to complete.

我想向“test.com”发送一个从 0 到 100 的请求,我拥有的代码将每隔一秒发送一个请求......这样程序将需要 100 秒才能完成。

What i would like to do is set 10 threads running all at the same time, making the thread 1 going from (0,10); thread 2 going from (10,20) ... and so on, in this way the program should take only 10 seconds or so in order to complete, is that possible ? how can acomplish it ?

我想做的是设置 10 个线程同时运行,使线程 1 从 (0,10) 开始;线程 2 从 (10,20) ... 等等,这样程序应该只需要 10 秒左右才能完成,这可能吗?怎么可能完成呢?

import java.io.InputStreamReader;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;

public class Palomo implements Runnable {
    String url = "http://test.com";
    HttpClient client = null;
    PostMethod method = null;
    BufferedReader br = null;
    String contents = null;

    public void run() {
        for (int i = 0; i <= 100; i++) {
            synchronized (this) {
                doPost(i);
            }
                      try {
        Thread.sleep(1000);
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
    }

    public void doPost(int i) {
        try {
            client = new HttpClient();
            method = new PostMethod(url);

            this.method.addParameter("myPostRequest", Integer.toString(i));

            client.executeMethod(method);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            method.releaseConnection();
        }
    }

    public static void main(String[] args) {
        new Thread(new Palomo()).start();
    }
}

Thanks a lot !

非常感谢 !

EDIT

编辑

Reading the indications you gave me, i created this horrible monster...

阅读你给我的指示,我创造了这个可怕的怪物......

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimpExec {
    public static void main(String args[]) {

        ExecutorService es = Executors.newFixedThreadPool(4);

        es.execute(new MyThread("A"));
        es.execute(new MyThread("B"));
        es.execute(new MyThread("C"));
        es.execute(new MyThread("D"));

        es.shutdown();
    }
}

class MyThread implements Runnable {
    String name;

    MyThread(String n) {
        name = n;
        new Thread(this);
    }

    public void run() {
        if (name=="A"){
            for (int i=1;i<=10;i++){
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        if (name=="B"){
            for (int i=10;i<=20;i++){
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        if (name=="C"){
            for (int i=20;i<=30;i++){
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        if (name=="D"){
            for (int i=30;i<=40;i++){
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

I know this is probably the most awful piece of code you ever watched, but is making exactly what i want, if you can give me some directions on how i should accomplish this in the right way that would be great.

我知道这可能是你看过的最糟糕的一段代码,但它正在制作我想要的代码,如果你能给我一些关于我应该如何以正确的方式完成这件事的指导,那就太好了。

THANKS A LOT FOR ALL YOUR GREAT ADVICES

非常感谢您的宝贵建议

回答by mkhelif

You should have a look at ExecutorServicewhich has been created to achieve this kind of things.

你应该看看ExecutorService已经创建来实现这种事情。

You can create a pool of 10 Threads using Executors.newFixedThreadPool(10);and then submit the tasks (Runnable) you want to be executed. The pool takes care of dispatching the tasks among the Threads.

您可以创建一个包含 10 个线程的池,Executors.newFixedThreadPool(10);然后提交Runnable要执行的任务 ( )。池负责在线程之间分派任务。

回答by Esko Luontola

You can create an Executor with Executors.newFixedThreadPool(10)and use it to execute each request as its own Runnable.

您可以使用Executors.newFixedThreadPool(10)创建一个 Executor并使用它来执行每个请求作为它自己的 Runnable。

回答by LuigiEdlCarno

Why don't you minize the time between the PostRequest. Using threads would have the same impact, as the time between the sends is smaller. the only thing you would accomplish by using threads on this changing the order in which the Posts are send To

为什么不最小化 PostRequest 之间的时间。使用线程会产生相同的影响,因为发送之间的时间更短。您唯一可以通过使用线程来改变帖子发送到的顺序来完成的事情

1, 11, 21,31,41 ... 2, 12,22,32,...

1, 11, 21,31,41 ... 2, 12,22,32, ...

Use

利用

Thread.CurrentThread.Sleep(100)

to lower the time between sends in your main application.

降低主应用程序中发送之间的时间。

Also you could run into trouble by letting multiple threads access the same HTTPClient. Even, if you synchronize the acces, the sending process would be serial, as the httpclient can only post 1 request at a time.

您也可能因为让多个线程访问同一个 HTTPClient 而遇到麻烦。即使您同步访问,发送过程也将是串行的,因为 httpclient 一次只能发布 1 个请求。

回答by Yair Zaslavsky

To add on the other comments, suggesting to use the ExecutorService( which is a good solution)
each one of the submitted Runnable objects should have the range of requests to handle.
. Your should consider having class extending Runnable.
The code for it can loook like -

补充其他评论,建议使用 ExecutorService(这是一个很好的解决方案),
每个提交的 Runnable 对象都应该有处理请求的范围。
. 您应该考虑让类扩展 Runnable。
它的代码看起来像 -

public class RangedPosts extends Runnable {
    private int start;
    private int end;
    public RangedPosts(int start,int end) {
        this.start = start;
        this.end = end;
    }

    public void run() {
       //Perform here a loop from start to end
    }
}

And then the usage should be a for loop, creating 10 runnable objects of RangePosts, passing them the range definition (start and end)

然后用法应该是一个for循环,创建10个RangePosts的可运行对象,将范围定义(开始和结束)传递给它们

回答by Vaibs

I have done something similar, I will share my first POC as it feels good to share.

我做过类似的事情,我将分享我的第一个 POC,因为分享感觉很好。

package test;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class ThreadCreater {

    // use getShape method to get object of type shape
    public Thread threadRunner(int start, int end, int threadCount, String url) {
    Thread thread = null;
    int tempEnd = 0;
    for (int i = 0; i <= end; i = i + 10) {
        start = i;
        tempEnd = i + 10;
        thread = getThread(start, tempEnd, threadCount, url);
        thread.start();
    }

    return null;
    }

    public static Thread getThread(int start, int end, int threadCount, String url) {
    Thread thread = new Thread() {
        public void run() {
        try {
            sendGET(start, end, url);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }

        private void sendGET(int start, int end, String url) throws Exception {
        url += "start=" + start + "&end=" + end;
        URL obj = new URL(url);
        // Send post request
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // basic reuqest header to simulate a browser request
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent",
            "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/51.0");
        con.setRequestProperty("Upgrade-Insecure-Requests", "1");
        con.setRequestProperty("Connection", "keep-alive");
        con.setDoOutput(true);

        // reading the HTML output of the POST HTTP request
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
        }
    };
    return thread;
    }

    public static void main(String[] args) {
    ThreadCreater obj = new ThreadCreater();
    int start = 0;
    int end = 100;
    int threadCount = 10;
    String url = "http://iseebug.com/test.php?";

    obj.threadRunner(start, end, threadCount, url);
    }

}

simple test.php code below

下面的简单 test.php 代码

<?php
/**
 * Created by PhpStorm.
 * User: polo
 * Date: 02-04-2017
 * Time: 22:28
 */


$q1 = isset($_GET['start']) ? $_GET['start'] : 'fakeMIP';
$q2 = isset($_GET['end']) ? $_GET['end'] : 'fakeMIP';


if($q1>=0&&$q2<=10){
echo $q2;
}elseif ($q1>=10&&$q2<=20){
    echo $q2;
}elseif ($q1>=20&&$q2<=30){
    echo $q2;
}elseif ($q1>=30&&$q2<=40){
    echo $q2;
}elseif ($q1>=40&&$q2<=50){
    echo $q2;
}elseif ($q1>=50&&$q2<=60){
    echo $q2;
}elseif ($q1>=60&&$q2<=70){
    echo $q2;
}elseif ($q1>=70&&$q2<=80){
    echo $q2;
}elseif ($q1>=80&&$q2<=90){
    echo $q2;
}elseif ($q1>=90&&$q2<=100){
    echo $q2;
}

Good luck.

祝你好运。

But i will prefer java's ExecutorService for high usage, for limited requirement , you can go for basic threading.

但是我更喜欢 java 的 ExecutorService 以实现高使用率,对于有限的要求,您可以选择基本线程。

Ping me on any help.

Ping 我有任何帮助。