package Samples;
/*Generated by MPS */
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CopyOnWriteArrayList;
import utils.ParallelLoopException;
public class ThreadSafeSample {
private static final String fixedFieldValue = "Fixed value for ever";
public ThreadSafeSample() {
}
public static void main(String[] args) throws InterruptedException {
// This sample shows that classes marked thread-safe will not be reported
// as inproperly used from within parallel for loops
// This is a thread safe class to exchange a single value between a producer and a consumer
// Open the DropBox class definition and notice the "@thread safe" annotation for the class
final DropBox<String> box = new DropBox<String>();
// A consumer thread reading and printing values exchanged through the drop box
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Received: " + box.retrieve());
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
});
thread.start();
final List<String> names = ListSequence.fromListAndArray(new ArrayList<String>(), "Joe", "Dave", "Alice");
{
final CountDownLatch latch_n0c = new CountDownLatch(ListSequence.fromList(names).count());
final List<Exception> exceptions_n0c = new CopyOnWriteArrayList<Exception>();
for (final String name : names) {
final String localA = name;
final Runnable runnable = new Runnable() {
public void run() {
try {
try {
// Notice no warning nor error reported
box.store(localA);
// If the DropBox class was annotated as "@non thread safe", we would get an error reported
// No annotation on the class would result in a warning
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} catch (RuntimeException e) {
ListSequence.fromList(exceptions_n0c).addElement(e);
} finally {
latch_n0c.countDown();
}
}
};
new Thread(runnable).start();
}
try {
latch_n0c.await();
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_n0c).addElement(e);
}
if (ListSequence.fromList(exceptions_n0c).isNotEmpty()) {
throw new ParallelLoopException("Some parallel calculations failed", exceptions_n0c);
}
}
// By annotating a local variable, field or parameter declaration as thread safe you indicate that calling methods
// on the object is thread-safe
// Alt + Enter on variable declarations will let you mark and unmark them as thread-safe
final String fixedValue = " fixed value ";
{
final CountDownLatch latch_u0c = new CountDownLatch(ListSequence.fromList(names).count());
final List<Exception> exceptions_u0c = new CopyOnWriteArrayList<Exception>();
for (final String name : names) {
final String localA = name;
final Runnable runnable = new Runnable() {
public void run() {
try {
String finalString = localA + fixedValue.toUpperCase() + fixedFieldValue;
log("Result: " + finalString);
} catch (RuntimeException e) {
ListSequence.fromList(exceptions_u0c).addElement(e);
} finally {
latch_u0c.countDown();
}
}
};
new Thread(runnable).start();
}
try {
latch_u0c.await();
} catch (InterruptedException e) {
ListSequence.fromList(exceptions_u0c).addElement(e);
}
if (ListSequence.fromList(exceptions_u0c).isNotEmpty()) {
throw new ParallelLoopException("Some parallel calculations failed", exceptions_u0c);
}
}
thread.interrupt();
}
private static void log(String message) {
System.out.println(message);
}
}