package Samples;
/*Generated by MPS */
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import jetbrains.mps.internal.collections.runtime.Sequence;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import utils.ParallelLoopException;
import java.util.concurrent.atomic.AtomicInteger;
public class ParallelForSample {
public ParallelForSample() {
}
public static void main(String[] args) {
// Some thread pools to use
final ExecutorService myPool = Executors.newFixedThreadPool(3);
final ExecutorService youPool = Executors.newFixedThreadPool(10);
// A collection of numbers to play with
final Iterable<Integer> numbers = ListSequence.fromListAndArray(new ArrayList<Integer>(), 1, 2, 3, 4, 5);
// The optional reference to a thread pool is set in the Inspector (Alt|Command + 2)
{
final CountDownLatch latch_i0d = new CountDownLatch(Sequence.fromIterable(numbers).count());
final List<Exception> exceptions_i0d = new CopyOnWriteArrayList<Exception>();
for (final int a : numbers) {
final int localA = a;
final Runnable runnable = new Runnable() {
public void run() {
try {
log("Starting calculation for number " + localA + " in thread " + Thread.currentThread());
Thread.sleep(localA * 1000);
// External (compiled) method calls can be annotated as thread-safe to indicate that they are safe to call
log("Finished calculation for number " + localA + " in thread " + Thread.currentThread());
} catch (RuntimeException e) {
ListSequence.fromList(exceptions_i0d).addElement(e);
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_i0d).addElement(e);
} finally {
latch_i0d.countDown();
}
}
};
myPool.execute(runnable);
}
try {
latch_i0d.await();
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_i0d).addElement(e);
}
if (ListSequence.fromList(exceptions_i0d).isNotEmpty()) {
throw new ParallelLoopException("Some parallel calculations failed", exceptions_i0d);
}
}
log("Done");
// References to non-final variables and parameters from within parallel loops are reported as errors
// Try making the following variable non-final (Alt + Enter)
final String doNotMessupWith = "The Shared State";
// Accessing non-thread-safe classes, such as lists, is reported as warnings
final List<String> names = ListSequence.fromListAndArray(new ArrayList<String>(), "Joe", "Dave", "Alice");
// Accessing thread-safe classes is considered ok
final AtomicInteger counter = new AtomicInteger(0);
{
final CountDownLatch latch_w0d = new CountDownLatch(Sequence.fromIterable(numbers).count());
final List<Exception> exceptions_w0d = new CopyOnWriteArrayList<Exception>();
for (final int b : numbers) {
final int localA = b;
final Runnable runnable = new Runnable() {
public void run() {
try {
log("Touching " + doNotMessupWith);
int messupWithMeSinceImlocal = 1;
messupWithMeSinceImlocal += 10;
log("Local variables can be used without restrictions " + messupWithMeSinceImlocal);
// Warning since we are accessing a non-local non-thread-safe object
ListSequence.fromList(names).removeElement("Joe");
List<String> localNames = ListSequence.fromList(new ArrayList<String>());
// Local references can be called without restrictions
ListSequence.fromList(localNames).addElement("Susan");
// Thread-safe objects are safe to use as well
log("Counter: " + counter.incrementAndGet());
Thread.sleep(localA);
} catch (RuntimeException e) {
ListSequence.fromList(exceptions_w0d).addElement(e);
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_w0d).addElement(e);
} finally {
latch_w0d.countDown();
}
}
};
youPool.execute(runnable);
}
try {
latch_w0d.await();
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_w0d).addElement(e);
}
if (ListSequence.fromList(exceptions_w0d).isNotEmpty()) {
throw new ParallelLoopException("Some parallel calculations failed", exceptions_w0d);
}
}
// Iterating over a collection of strings
// No thread pool is set (Alt|Command + 2) so using threads directly
{
final CountDownLatch latch_ab0d = new CountDownLatch(ListSequence.fromList(names).count());
final List<Exception> exceptions_ab0d = new CopyOnWriteArrayList<Exception>();
for (final String c : names) {
final String localA = c;
final Runnable runnable = new Runnable() {
public void run() {
try {
log("Name: " + localA);
if (localA == "Joe") {
throw new RuntimeException("test");
}
} catch (RuntimeException e) {
ListSequence.fromList(exceptions_ab0d).addElement(e);
} finally {
latch_ab0d.countDown();
}
}
};
new Thread(runnable).start();
}
try {
latch_ab0d.await();
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_ab0d).addElement(e);
}
if (ListSequence.fromList(exceptions_ab0d).isNotEmpty()) {
throw new ParallelLoopException("Some parallel calculations failed", exceptions_ab0d);
}
}
// Shutdown the thread pools
myPool.shutdown();
youPool.shutdown();
}
private static void log(String message) {
System.out.println("Logging: " + message);
}
}