Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单线程程序与多线程程序(测量运行时间)_Java_Multithreading_Single Threaded - Fatal编程技术网

Java 单线程程序与多线程程序(测量运行时间)

Java 单线程程序与多线程程序(测量运行时间),java,multithreading,single-threaded,Java,Multithreading,Single Threaded,我想知道我是否需要测量经过的时间,然后单线程程序是一个好方法,或者多线程程序是一个好方法 下面是我的单线程程序,它测量我们服务的时间- private static void serviceCall() { histogram = new HashMap<Long, Long>(); keys = histogram.keySet(); long total = 5; long runs = total; while (runs >

我想知道我是否需要测量经过的时间,然后单线程程序是一个好方法,或者多线程程序是一个好方法

下面是我的单线程程序,它测量我们服务的时间-

private static void serviceCall() {

    histogram = new HashMap<Long, Long>();
    keys = histogram.keySet();
    long total = 5;
    long runs = total;

    while (runs > 0) {

        long start_time = System.currentTimeMillis();
        result = restTemplate.getForObject("SOME URL",String.class);
        long difference = (System.currentTimeMillis() - start_time);

        Long count = histogram.get(difference);
        if (count != null) {
            count++;
            histogram.put(Long.valueOf(difference), count);
        } else {
            histogram.put(Long.valueOf(difference), Long.valueOf(1L));
        }
        runs--;
    }

    for (Long key : keys) {
        Long value = histogram.get(key);
        System.out.println("MEASUREMENT " + key + ":" + value);
    }
}
这意味着
1
呼叫在
163毫秒后返回<代码>3
呼叫在
42毫秒后返回
等等

我也尝试过使用多线程程序来测量所经过的时间。这意味着用几个线程并行地运行服务,然后测量每个线程占用的资源量

下面是代码-

//create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(10);

// queue some tasks 
for (int i = 0; i < 1 * 5; i++) {
    service.submit(new ThreadTask(i, histogram));
}


public ThreadTask(int id, HashMap<Long, Long> histogram) {
    this.id = id;
    this.hg = histogram;
}


@Override
public void run() {

    long start_time = System.currentTimeMillis();

    result = restTemplate.getForObject("",  String.class);
    long difference = (System.currentTimeMillis() - start_time);

    Long count = hg.get(difference);
    if (count != null) {
        count++;
        hg.put(Long.valueOf(difference), count);
    } else {
        hg.put(Long.valueOf(difference), Long.valueOf(1L));
    }

}
一个电话在176毫秒内返回,依此类推


所以我的问题是,为什么多线程程序比上面的单线程程序花费更多的时间?如果我的多线程程序中有一些循环漏洞,有人能帮我改进一下吗?

您的多线程程序可能会同时发出所有请求,这会给服务器带来更大的压力,导致服务器对所有请求的响应速度变慢

顺便说一句,您执行更新的方式不是线程安全的,因此在多线程场景中,如果进行了足够的尝试,您的计数可能会下降


例如,线程A和线程B都会在100毫秒内同时返回。直方图中100的计数为3。A得3分。B得3分。A将3更新为4。B更新3至4。A将值4放入直方图中。B将值4放入直方图中。现在有两个线程认为它们增加了计数,但直方图中的计数只反映了增加一次。

需要担心的是,它看起来不像是同步的。如果有多个线程正在向其写入,则需要将其写入。也就是说,我不确定这是否是不同时间的原因。您是否多次运行此测试?每次的表演看起来都一样吗?你会在程序启动并运行一段时间后再开始计时吗?这可能更多地是关于JVM启动和JIT编译器优化,而不是您的任务。至于你的其他问题,是的,我也试了好几次。。所以你想到的唯一一个循环孔是hg不同步,对吗?你知道有什么更好的方法来衡量我可以遵循的时间吗?我怀疑一个线程可以重用一个连接,从而加快后续请求的速度,而不同的线程需要分别建立一个连接。(您可以看到,在多线程示例中重复了最糟糕的计时)关键是端到端时间。多个线程总是要比一个线程使用更多的CPU,但是您可能希望在更长的测试中,端到端时间更好。我会运行测试至少10秒。不确定什么是“循环孔”。我只是说,你应该考虑事先提出请求来加热JVM,然后开始你的挂钟计时测试。但我认为@digitaljoe所说的是正确的。那么你有什么建议吗?我应该制作一个单线程程序来测量经过的时间?测试@Nevzz03的目的是什么。查看您可以同时执行多少个请求?一次做一个会使每个请求更快,但所有请求都会在较慢的时间内完成。谢谢digitaljoel的建议。你能告诉我在哪里需要修改代码来解决这个问题吗?任何一个例子都会让我很好地理解这个场景。@Gray,我需要加强这个测试,同时对我的服务进行大约1000或10000次调用(因为这将是生产中的实际行为),并测量所经过的时间。因为在生产过程中,会有大约数百万的电话打给我们的服务。因此,这就是我试图衡量我的服务绩效的原因。我确信我的多线程程序肯定有问题。不,我认为你的计时应该是@Nevzz03。要知道,系统的性能更多地取决于并发请求,而不是任何一个请求被调用1000次。您可能希望调整线程池的大小,并限制并发请求的数量,以优化每秒的请求。
//create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(10);

// queue some tasks 
for (int i = 0; i < 1 * 5; i++) {
    service.submit(new ThreadTask(i, histogram));
}


public ThreadTask(int id, HashMap<Long, Long> histogram) {
    this.id = id;
    this.hg = histogram;
}


@Override
public void run() {

    long start_time = System.currentTimeMillis();

    result = restTemplate.getForObject("",  String.class);
    long difference = (System.currentTimeMillis() - start_time);

    Long count = hg.get(difference);
    if (count != null) {
        count++;
        hg.put(Long.valueOf(difference), count);
    } else {
        hg.put(Long.valueOf(difference), Long.valueOf(1L));
    }

}
{176=1, 213=1, 182=1, 136=1, 155=1}