多线程延迟的原因

时间:2019-04-14 17:01:58

标签: java multithreading

我用Java编写了一个程序,可以在for循环中打印10万。

for (int i =0;i<1000000;i++){
     System.out.println(i);
}

大约花了7.5 seconds

我用Java语言编写了一个自定义类,该类实现了Runnable接口,它以2个参数为限制来打印2个值之间的值。

public class ThreadCustom implements  Runnable {

    int start;
    int end;
    String name;


    ThreadCustom(int start, int end, String name){
        this.start = start;
        this.end = end;
        this.name = name;

    }
    @Override
    public void run() {
       for(int i =start; i<=end;i++){
            System.out.println(i);
        }
    }
}

我创建了10个自定义线程类的对象,为每个对象分配了10万个数字进行打印,因此最后我得到了所有10 hundred thousands的打印内容(不一定是按顺序排列),但是大约需要9.5秒。

2 seconds delay的原因是什么?那是因为在线程之间进行时间切片和上下文切换吗?我正在执行一个Java进程,它产生了10个线程。我在想正确的方向吗?

已更新:对System.out.println进行了评论,以查看其在发生迭代时的性能。

无线程的打印时间

2019-04-14 22:18:07.111   // start
2019-04-14 22:18:07.116 // end

使用ThreadCustom类:

2019-04-14 22:26:42.339
2019-04-14 22:26:42.341

2 个答案:

答案 0 :(得分:1)

多余的时间通过两种方式花费: 1)设置每个线程执行上下文所涉及的开销 2)可能产生的线程数量超过了主处理器中可用逻辑处理器的数量

由于递增循环和打印整数所需的处理量很小,因此在大多数情况下,这将导致并行环境下的性能下降。

但是,如果您要进行诸如在每次迭代期间计算任何给定图像上不同像素颜色的操作,那么在使用多线程时,您将看到显着的性能优势。

答案 1 :(得分:1)

  

我用Java编写了一个程序,用于在for循环中打印[1百万]。我创建了10个自定义线程类的对象,但是,这大约需要9.5秒。延迟2秒的原因是什么?

仅当线程可以独立工作时它们才会更快。在将数字打印到@Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence charSequence) { String charString = charSequence.toString(); if (charString.isEmpty()) { data = pricelist; } else { List<HotelsListObj> filteredList = new ArrayList<>(); for (HotelsListObj row : pricelist) { // name match condition. this might differ depending on your requirement // here we are looking for name or phone number match if (row.getHotelPrice().toLowerCase().contains(charString.toLowerCase()) || row.getHotelPrice().contains(charSequence)) { filteredList.add(row); } } data = filteredList; } FilterResults filterResults = new FilterResults(); filterResults.values = data; return filterResults; } @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) { data = (ArrayList<HotelsListObj>) filterResults.values; notifyDataSetChanged(); } }; } 的情况下,所有线程都试图争夺对相同资源System.out的访问,该资源是同步的System.out。这意味着大多数时间都浪费在等待另一个线程释放对PrintStream的锁定上。线程程序的任何其他“延迟”很可能是由于锁争用和线程之间的上下文切换引起的。

要正确测试线程速度,您需要在每个线程中运行某种独立的CPU任务。多次计算System.out是一个更好的例子。在较新的Macbook上,我可以在〜8.1秒内进行10亿次调用(带有b)Math.sqrt(...),但是10个线程可以并行地在〜1.1秒内进行1亿次调用​​。但是,您可能会说,等待10 * 1.1> 8秒。我有4个核心,因此在运行10个线程时,有很多CPU进出。 4个线程各自执行250m耗时2.1秒,与单线程示例相比,该时间更接近8.1秒。

最后,Java性能测试非常困难。我敢打赌,如果您多次运行两个程序,将会看到一些不同的结果。任何快速运行的程序实际上都不能很好地判断速度,或者充其量只是一个很粗略的近似值。另外,您还需要注意,否则热交换编译器可能会在运行时优化循环,因此您需要尝试进行实际工作。