【问题标题】:Faster multiple threading vs single threading更快的多线程与单线程
【发布时间】:2015-11-26 19:43:34
【问题描述】:

我正在实施一个在线商店,客户可以在其中下订单,我的程序会生成客户是谁以及他们购买了哪些商品的摘要。

public class Summarizer{
private TreeSet<Order> allOrders = new TreeSet<Order>(new OrderComparator());

public void oneThreadProcessing(){
    Thread t1;
    for(Order order: allOrders){
        t1 = new Thread(order);
        t1.start();
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void multipleThreadProcessing(){
    Thread[] threads = new Thread[allOrders.size()];
    int i = 0;
    for(Order order: allOrders){
        threads[i] = new Thread(order);
        threads[i].start();
        i++;
    }
    for(Thread t: threads){
        try {
            t.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
    }
}

public static void main (String[] args) {
    Summarizer s = new Summarizer();
    long startTime = System.currentTimeMillis();
    s.oneThreadProcessing();
    long endTime = System.currentTimeMillis();
    System.out.println("Processing time (msec): " + (endTime - startTime));

    System.out.println("-------------Multiple Thread-------------------------------");
    long startTime1 = System.currentTimeMillis();
    s.multipleThreadProcessing();
    long endTime1 = System.currentTimeMillis();
    System.out.println("Processing time (msec): " + (endTime1 - startTime1));

这是我的订单类:

   public class Order implements Runnable, Comparable<Order> {
            private int clientId;

        @Override
        public void run() {
        /*
        Print out summary in the form:
        Client id: 1001
        Item: Shoes, Quantity: 2, Cost per item: $30.00, Total Cost: $60.00
        Item: Bag, Quantity: 1, Cost per item: $15.00, Total Cost: $15.00
        Total: $75.00
        /*

    }
}

假设我在这个 TreeSet 中填写了按客户 ID 号排序的特定日期的所有订单,我想只使用一个线程然后使用多个线程生成所有这些订单的摘要并比较性能。要求是让多线程性能更好,我会假设它会是但每次我运行我的主要方法时。多线程实际上几乎总是较慢。难道我做错了什么?我知道人们永远无法确定多线程程序会更快,但由于我还没有处理任何锁定,所以我的程序在 multipleThreadedProcessing() 中不应该更快吗?有什么方法可以确保它更快吗?

【问题讨论】:

    标签: java multithreading performance


    【解决方案1】:

    多线程并不是撒在代码上以使其运行得更快的灵丹妙药。这需要仔细考虑你在做什么。

    我们来分析一下你写的多线程代码。

    你有很多Orders(多少个?几十个?几百个?几千个?几百万个?),当执行时,每个订单都会打印到屏幕上。这意味着您可能会产生大量线程,因此每个线程都会花费大部分时间等待System.out 可用(因为它会被其他线程占用)。每个线程都需要 OS 和 JVM 参与,此外还需要 CPU 时间和内存资源;那么为什么这样的多线程方法应该比单线程运行得更快呢?单个线程不需要额外的内存,也不需要额外的上下文切换,也不必等待System.out。所以自然会更快。

    要让多线程版本更快地工作,您需要想办法在线程之间分配工作,而不会造成不必要的资源争用。一方面,您可能不需要多个线程来执行写入屏幕的I/O 任务。多个线程写入System.out 只会相互阻塞。如果您需要写入多个 IO 设备,则为每个设备创建一个或多个线程(取决于设备的性质)。 计算任务有时可以更快地并行执行,但是:

    A) 您不需要比 CPU 拥有的内核数量更多的线程来执行计算工作。如果你有太多 CPU 密集型线程,它们只会浪费时间进行上下文切换。

    B) 您需要对并行处理进行推理,并对其进行彻底的计划。给每个线程分配一块需要完成的计算任务,然后组合每个线程的结果。

    【讨论】:

    • 关于如何让它更快的任何建议?不使用 System.out 而只是将正在打印的字符串分配给一个名为 String summary 的实例变量。然后使用 getter 访问每个订单的摘要?
    • @samz_manu 我已经稍微扩展了答案,看看是否有帮助。是的,这将消除对 System.out 的不必要争用,但仍会(可能)为许多线程创建 WAY。
    猜你喜欢
    • 2016-08-09
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    相关资源
    最近更新 更多