Home > OS >  Iterating over IntStream to print values
Iterating over IntStream to print values

Time:01-01

In the below example, I am using the field number in IntStream.range(0, 10).forEach(number -> new Thread(r).start()); even though it is not being used. Is there a way to rewrite it so that I do not have to use the unused number variable?

    import javax.annotation.concurrent.NotThreadSafe;
    import java.util.stream.IntStream;
    
    public class LearnThreads {
        public static void main(String[] args)  {
            UnsafeThreadClass counter = new UnsafeThreadClass();
            Runnable r = () -> {
                try {
                    System.out.println(counter.getValue()   " : Thread - "  Thread.currentThread());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
            IntStream.range(0, 10).forEach(number -> new Thread(r).start());
        }
    }
    
    
    @NotThreadSafe
    class UnsafeThreadClass {
        private int value;
    
        public synchronized int getValue() throws InterruptedException {
            Thread.sleep(1000);
            return value  ;
        }
    }

CodePudding user response:

No; you must specify a name for the consumer, however why use a stream?

This is simpler and more readable:

for (int i = 0; i < 10; i  ) {
    new Thread(r).start();
}

If you must use a Stream, try limit() instead:

Stream.generate(() -> new Thread(r)).limit(10).forEach(Thread::start);

But there's an ugly producer in there.

CodePudding user response:

As an alternative you can create a lightweight virtual List to a using static method Collections.nCopies() (which behaves like a regular List but it's not baked by a real data structure, basically it's a wrapper around the provided reference and its memory footprint is tiny).

Here's how you can fire 10 Runnable tasks using Stream API and nCopies():

Runnable r = // initializing the task
        
Collections.nCopies(10, r).stream().map(Thread::new).forEach(Thread::start);

The same can be done using without Streams using Iterable.forEach():

Runnable r = // initializing the task

Collections.nCopies(10, r).forEach(task -> new Thread(task).start());
  • Related