5

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

我想做的是设置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();
    }
}

非常感谢 !

编辑

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

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();
                }
            }
        }
    }
}

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

非常感谢您提供的所有重要建议

4

5 回答 5

5

你应该看看ExecutorService,它是为实现这种事情而创建的。

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

于 2012-10-11T08:19:10.300 回答
4

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

于 2012-10-11T08:19:27.853 回答
0

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

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

采用

Thread.CurrentThread.Sleep(100)

减少主应用程序中发送之间的时间。

此外,让多个线程访问同一个 HTTPClient 可能会遇到麻烦。甚至,如果您同步访问权限,发送过程将是串行的,因为 httpclient 一次只能发布 1 个请求。

于 2012-10-11T08:21:14.580 回答
0

添加其他评论,建议使用 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
    }
}

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

于 2012-10-11T08:45:43.863 回答
0

我做过类似的事情,我将分享我的第一个 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);
    }

}

下面是简单的 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;
}

祝你好运。

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

向我寻求任何帮助。

于 2017-04-02T17:32:36.390 回答