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());