0

Is there a way to process each class attribute in parallel using java 8 lambda?

For example, for a given Car.java:

public class Car{
    private String color;
    private String model;
    private float value;
    private float tax;
    // and others attributes
    .
    .
    .
    // Getters and Setters
}

I would like to make some process over color, model, value, tax, etc in parallel. So basically the wished logic would be:

parallel processing:
    - color
    - model
    - value
    - tax

then join and update Car.java object instance fields. 

Please, note that this problem is independent of the number of cars instances. It could be just one or many.

OneNoOne
  • 587
  • 7
  • 23
  • Solely depends on what exactly you intend to do. Unfortunately, your question is pretty broad and unclear in its current state (voting for close). – Zabuzard Oct 30 '19 at 19:10
  • What do you mean by "some process"? You need to first decide what you want to achieve. – Kayaman Oct 30 '19 at 19:12
  • 1
    What you want to do isn't going to be possible using parallelStream which is meant to do classical parallelization where you're doing essentially the same operation in each thread, but on different instances of the same class. – Don Hosek Oct 30 '19 at 19:23
  • What you really want to do is some form of multithreading where you'll have a process for each of your attributes which will each execute their own expensive (timewise) logic and then join the threads together at the end. You should probably start by examining the classes and interfaces in java.util.concurrent and work out your plan from there. Off the top of my head, I'd start by looking at how you can use CompletableFuture. – Don Hosek Oct 30 '19 at 19:26

1 Answers1

1

I was curious, how that would look like. Assuming the restriction holds, that the processing of each of the properties is independent of one another, that would be one way to utilize parallelStream(). But I doubt very much, that this pays off due to the overhead of the parallel machinery. One could make it even more outlandish using reactive streams, e.g. RxJava.

public class Car{
    public String color;
    public String model;
    public float value;
    public float tax;

    public Car(String color, String model, float value, float tax) {
        this.color = color;
        this.model = model;
        this.value = value;
        this.tax = tax;
    }

    @Override
    public String toString() {
        return "Car{" +
                "color='" + color + '\'' +
                ", model='" + model + '\'' +
                ", value=" + value +
                ", tax=" + tax +
                '}';
    }
}

@Test
public void process() {
    List<Consumer<Car>> processors = Arrays.asList(
            c -> c.color = printThread(c.color.toLowerCase()),
            c -> c.model = printThread(c.model.toLowerCase()),
            c -> c.value = printThread(c.value * c.value),
            c -> c.tax = printThread(c.tax / c.tax));

    Arrays.asList(new Car("Red", "AlphaGorilla", 1f, 0.5f), new Car("Blue", "Bloated++", 10f, 0.2f))
            .parallelStream().forEach(c -> {
        System.out.println(c);
        processors.parallelStream().forEach(p -> {
            p.accept(c);
            fakeExpensiveComputation();
        });
        System.out.println(c);
    });
}

private <T> T printThread(T smthg) {
    System.out.println(String.format("Calculated value %s in thread %d", smthg.toString(), Thread.currentThread().getId()));
    return smthg;
}

private void fakeExpensiveComputation() {
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        throw new RuntimeException();
    }
}
Curiosa Globunznik
  • 3,129
  • 1
  • 16
  • 24