How does parallel stream "know" to use the enclosing ForkJoinPool? - java

In Java 8 one can set a custom forkJoinPool to be used by parallel streams rather than the common pool.
forkJoinPool.submit(() -> list.parallelStream().forEach(x ->{...} ))
My question is how does it technically happen?
The stream is not in any way aware it was submitted to a custom forkJoinpool and has no direct access to it. So how are the correct threads eventually used for processing the stream's tasks?
I tried looking at the source code but to no avail. My best guess is some threadLocal variable set at some point when submitting and then used by the stream later on. If so, why would the language developers choose such a way to implement the behaviour rather than, say, dependency injecting the pool into the stream?
Thanks!

From what I've read the code, the decisions is made only based on the initial thread that triggers the computation, inside the method ForkJoinTask::fork, that literally does a check against what thread triggered this (also in it's documentation):
Thread.currentThread()) instanceof ForkJoinWorkerThread
So if an instance of ForkJoinWorkerThread has started this (this is what you would get via a custom ForkJoinPool), use whatever the pool already exists and this task run in; otherwise (if it is a different thread that is not an instance of ForkJoinWorkerThread) use:
ForkJoinPool.common.externalPush(this);
Also interesting that ForkJoinWorkerThread is actually a public class, so you could start the computation inside an instance of it, but still using a different pool; though I have not tried this.

The java.util.stream.ForEachOps.ForEachOp#evaluateParallel method calls invoke():
#Override
public <S> Void evaluateParallel(PipelineHelper<T> helper,
Spliterator<S> spliterator) {
if (ordered)
new ForEachOrderedTask<>(helper, spliterator, this).invoke();
else
new ForEachTask<>(helper, spliterator, helper.wrapSink(this)).invoke();
return null;
}
which in turn calls java.util.concurrent.ForkJoinTask#doInvoke:
private int doInvoke() {
int s; Thread t; ForkJoinWorkerThread wt;
return (s = doExec()) < 0 ? s :
((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
(wt = (ForkJoinWorkerThread)t).pool.
awaitJoin(wt.workQueue, this, 0L) :
externalAwaitDone();
}
As seen in the above method, it finds out the current thread using Thread.currentThread().
It then uses the .pool field as in (wt = (ForkJoinWorkerThread)t).pool, which gives the current pool that this thread is running in:
public class ForkJoinWorkerThread extends Thread {
final ForkJoinPool pool; // the pool this thread works in

Related

Read lock while Writing

I need help in understanding the below code :
private Predicate composedPredicate = null;
public boolean evaluate(Task taskData) {
boolean isReadLock = false;
try{
rwl.readLock().lock();
isReadLock = true;
if (composedPredicate == null) {
rwl.readLock().unlock();
isReadLock = false;
rwl.writeLock().lock();
if (composedPredicate == null) {
//write to the "composedPredicate" object
}
}
}finally {
if (isReadLock) {
rwl.readLock().unlock();
}else{
rwl.writeLock().unlock();
}
}
return composedPredicate.test(taskData);
}
What will happen if we don't use Read Locks in the above code?
Like :
public boolean evaluate(Task taskData) {
//boolean isReadLock = false;
try{
//rwl.readLock().lock();
//isReadLock = true;
if (composedPredicate == null) {
//rwl.readLock().unlock();
//isReadLock = false;
rwl.writeLock().lock();
if (composedPredicate == null) {
//write to the "composedPredicate" object
}
}
}finally {
rwl.writeLock().unlock();
}
return composedPredicate.test(taskData);
}
Do we really need Read locks while we are only writing the data?
What is the difference between the above two codes?
Should we use Read locks even for accessing the object(composedPredicate) for null check?
The first code that you posted is a correct implementation of the double-checked locking approach in Java using a read/write lock.
Your second implementation without a read-lock is broken. The memory model allows writes to be reordering from the perspective of another thread seeing the result of the writes to memory.
What could happen is that you could be using a not-fully initialized instance of Predicate in the thread that is reading it.
Example with your code:
We have thread A and B both running evaluate and composedPredicate is null initially.
A: sees composedPredicate is null
A: write-locks
A: creates an instance of an implementation of Predicate
A: initializes this instance in the constructor
A: assigns the instance to the the shared variable composedPredicate
A: unlocks the write lock
B: sees composedPredicate is not null
B: runs composedPredicate.test(taskData);
HOWEVER, the compiler, the JVM, or the hardware architecture of your system reordered steps 4 and 5 of thread A, and assigned the address of the Predicate instance of the shared field before it was initialized (this is allowed by the Java Memory model)
composedPredicate.test(taskData); is run using a not-fully initialized instance and your code has random unexpected errors in production resulting in great losses to your company (potentially that happens .. depends on the system that you're building)
Whether or not the reordering of step 4 and 5 happens depends on many factors. Maybe it only does under heavy system load. It may not happen at all on your OS, hardware, version of JVM, etc. (But on the next version of the JVM, your OS, or when you move your application to a different physical machine, it may suddenly start happening)
Bad idea.
This code is simular to an old 'Singleton-pattern' wich makes use of the synchronozed blocks. E.g.
class Singleton
{
volatile Singleton s;
public static Singleton instance()
{
if(s == null)
{
synchronized(Singleton.class)
{
if(s == null)
s = new Singleton();
}
}
return s;
}
}
Notice the double 'null-check' where only the second one is synchronozed. The reason for doing the first 'null-check' is to prevent the blocking of threads if the instance() method is called (because when not null, it can proceed without synchronization).
Your first code is doing the same. First it checks if there is something assigned to composedPredicate. And if that isnt the case, only than will it aquire a writingLock (wich blocks all other Thread oposed to readLocks, which only blocks writeLocks).
The main difference with the 'singleton-pattern' and your code is that your value can be reassignes. This can only happen safly if it makes sure nobody is reading the value during modification. By removing the readLock you basically create a possibility that a thread may get undefined results (if not a crash) when accessing the composedPredicate while another Thread is modifying that same field.
So to answer your questions:
1. You dont need a readLock for writing, only a writeLock (wich will block all other Threads whonare trying to lock). But in this design-pattern you cannot leave it out.
2. & 3. See explanation above.
Hope this was enough to get a grasp of this pattern.
EDIT
As commented by Erwin Bolwidt , the above pattern is considered broken (without the 'volatile' keyword) due to compiler/CPU code optimization (where read/write actions may happen out of order). In the linked blog there are examples for alternatives/fixes for this problem. It turns out the 'volatile' keyword creates a barier which disallows reordering of read and write operations by either the compiler or CPU optimization, and thus 'fixes' the 'double-checked-locking' pattern described above.

Are accumulators thread-safe?

I'm using accumulators and wanted to know if these objects are thread-safe?
accumInt is a type of AccumulatorParam<Integer>.
// Current value accumInt -> 6
AccumulatorThread t1 = new AccumulatorThread();
t1.setAccum(accumInt);
t1.setValueToAdd(5);
AccumulatorThread t2 = new AccumulatorThread();
t2.setAccum(accumInt);
t2.setValueToAdd(7);
new Thread(t1).start();
new Thread(t2).start();
System.out.println(accumInt.value()); // 11 or 13 or 18
AccumlatorThread class:
class AccumulatorThread implements Runnable {
Accumulator<Integer> accum;
Integer valueToAdd;
public Integer getValueToAdd() {
return valueToAdd;
}
public void setValueToAdd(Integer valueToAdd) {
this.valueToAdd = valueToAdd;
}
public Accumulator<Integer> getAccum() {
return accum;
}
public void setAccum(Accumulator<Integer> accum) {
this.accum = accum;
}
public void run() {
System.out.println("Value to Add in Thread : "+valueToAdd);
accum.add(valueToAdd);
}
}
The behavior shows that it is not a thread safe. Am I missing something?
OOC why are you both setting and reading the accumulator in the same program? Accumulators are generally added to by the worker threads and may only be read by the driver thread.
Worker1: accumulator.add(increment)
Worker2: accumulator.add(someOtherIncrement)
Driver: println(accumulator.value)
Now you are asking about mulithreading for setting/reading values in different threads on the driver. To what purpose? In that case just use a local JVM AtomicInteger or AtomicLong.
Accumulators are variables that are only “added” to through an associative operation and can therefore be efficiently supported in parallel.
Accumulators are not thread-safe. Only SparkContext can be used in multiple threads.
To expand on the other two great answers from #javadba and #zsxwing.
My understanding of Apache Spark is that they may or may not be thread-safe. It does not really matter. Since the driver is "far away" from its workers (they usually talk to each other over the network or at least between JVMs -- unless it's local mode) all updates to an accumulator arrive in messages that are processed one by one and therefore ensure single-threaded update to the accumulator.
Accumulators are not thread-safe, in fact they do not need to be thread-safe. For executors, accumulators are write only variables, they can be added by executors and they can be read by the driver. Driver makes use of DAGScheduler.updateAccumulators method to update values of accumulators after task is completed, and this method is called only from a thread that runs scheduling loop. At a time, only one task completion event is handled. That's why there is no need for accumulators to be thread-safe.

"escape" element in LinkedBlockingQueue

I am circling through LinkedBlockingQueue millions of Strings.
The reading thread should end its execution when there are no more items in source.
I thought about putting a dummy value like "SHUTDOWN" in LinkedBlockingQueue.
The reader does this:
while ((data = (String)MyLinkedBlockingQueue.take()).equals("SHUTDOWN") == false) {
//read and live
}
Is it efficient to execute equals on every string? If not what can I use instead?
You are on the right track. This is the standard idiom for finishing processing of a BlockingQueue, it's called the "poison pill". i usually implement it using a special private static final instance so you can do object equality and don't risk overlapping with a real value. e.g.:
private static final String SHUTDOWN = new String("SHUTDOWN"); // use new String() so you don't get an interned value
public void readQueue() {
while ((data = (String)MyLinkedBlockingQueue.take()) != SHUTDOWN) {
//read and live
}
}
public void shutdownQueue() {
MyLinkedBlockingQueue.put(SHUTDOWN);
}
You can also think of using poll() and ending the loop when it returns null.
This could be implemented so that you don't have to check for the "poison pill" every time. Consider making use of a ThreadPoolExecutor that works on your LinkedBlockingQueue. When you want to shut down processing, call the shutdown() method on the executor object. From the documentation of that method:
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
See this post if you're interested in shutting down processing immediately while tasks are still pending in the queue: With a Java ExecutorService, how do I complete actively executing tasks but halt the processing of waiting tasks?

Stopping a threadpool on satisfied condition

I'm using the ExecutorService to process thousands of small independent tasks. Each task, on completion, stores the result (which is either true of false).
So, instead of processing all of the tasks, I want to shutdown the threadpool prematurely, if a task has found the answer!
It feels like I'm missing something very obvious here...
Consider using the invokeAny method. It returns when just one is done.
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html#invokeAny(java.util.Collection)
The desire you express reminds me of a Klein bottle, where there's little distinction maintained between what's "inside" and what's "outside." Here, the tasks submitted to the ExecutorService need to know that they must notify a latching gate outside the thread pool and shut it down when first transitioning from having seen no true task outcomes to having seen at least one.
I won't write the code for you, but I'll sketch the solution. It may help to define an interface on which the tasks must call when they complete:
interface TaskObserver
{
void completed(boolean result);
}
Each task instance can be constructed with a reference to such a TaskObserver, on which the task body will call just before it completes and yields control back to the invoking ExecutorService. You could even write a base class to assist in participating in this protocol:
public abstract class ObservableTask implements Callable<Boolean>
{
protected ObservableTask(TaskObserver observer)
{
if (null == observer)
throw NullPointerException();
observer_ = observer;
}
public final Boolean call()
{
final boolean result = evaluate();
observer_.completed(result);
return result;
}
protected abstract boolean evaluate();
private final TaskObserver observer_;
}
Alternately, instead of using extension to define tasks, you could write a concrete class like this that accepts a reference to a Callable<Boolean> in its constructor in addition to the TaskObserver reference, and works through delegation instead.
Moving on, the implementation of TaskObserver will store an AtomicBoolean, which must be set to false initially. The body of the completed(boolean) method must attempt to set the AtomicBoolean from false to true if the result passed to completed(boolean) is true. If the transition from false to true is successful, shut down the ExecutorService and stop submitting any more tasks; any subsequent calls calls to the TaskObserver will come from tasks that had already been submitted and were too far along to comply with a cancellation request.
public void complete(boolean result)
{
if (result &&
latch_.compareAndSet(false, true))
{
// Set a flag to cease submitting new tasks.
service_.shutdownNow();
if (!service_.awaitTermination(timeoutMagnitude, timeoutUnit))
{
// Report a problem in shutting down the pool in a timely manner.
}
}
}
If that's not enough of a push to get you started, please follow up with additional questions.

How to have one java thread wait for the result of another thread?

I frequently need to have a thread wait for the result of another thread. Seems like there should be some support for this in java.util.concurrent, but I can't find it.
Exchanger is very close to what I'm talking about, but it's bi-directional. I only want Thread A to wait on Thread B, not have both wait on each other.
Yes, I know I can use a CountDownLatch or a Semaphore or Thread.wait() and then manage the result of the computation myself, but it seems like I must be missing a convenience class somewhere.
What am I missing?
UPDATE
// An Example which works using Exchanger
// but you would think there would be uni-directional solution
protected Exchanger<Integer> exchanger = new Exchanger<Integer>();
public void threadA() {
// perform some computations
int result = ...;
exchanger.exchange(result);
}
public void threadB() {
// retrieve the result of threadA
int resultOfA = exchanger.exchange(null);
}
Are you looking for Future<T>? That's the normal representation of a task which has (usually) been submitted to a work queue, but may not have completed yet. You can find out its completion status, block until it's finished, etc.
Look at ExecutorService for the normal way of obtaining futures. Note that this is focused on getting the result of an individual task, not rather than waiting for a thread to finish. A single thread may complete many tasks in its life time, of course - that's the whole point of a thread pool.
So far, it seems like BlockingQueue may be the best solution I've found.
eg.
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1);
The waiting thread will call queue.take() to wait for the result, and the producing queue will call queue.add() to submit the result.
The JDK doesn't provide a convenience class that provides the exact functionality you're looking for. However, it is actually fairly easy to write a small utility class to do just that.
You mentioned the CountDownLatch and your preference regarding it, but I would still suggest looking at it. You can build a small utility class (a "value synchronizer" if you will) pretty easily:
public class OneShotValueSynchronizer<T> {
private volatile T value;
private final CountDownLatch set = new CountDownLatch(1);
public T get() throws InterruptedException {
set.await();
return value;
}
public synchronized void set(T value) {
if (set.getCount() > 0) {
this.value = value;
set.countDown();
}
}
// more methods if needed
}
Since Java 8 you can use CompletableFuture<T>. Thread A can wait for a result using the blocking get() method, while Thread B can pass the result of computation using complete().
If Thread B encounters an exception while calculating the result, it can communicate this to Thread A by calling completeExceptionally().
What's inconvenient in using Thread.join()?
I recently had the same problem, tried using a Future then a CountdownLatch but settled on an Exchanger. They are supposed to allow two threads to swap data but there's no reason why one of those threads can't just pass a null.
In the end I think it was the cleanest solution, but it may depend on what exactly you are trying to achieve.
You might use java.util.concurrent.CountDownLatch for this.
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html
Example:
CountDownLatch latch = new CountDownLatch(1);
// thread one
// do some work
latch.countDown();
// thread two
latch.await();

Categories