I have a question about the "correctness" of the RunnableFuture interface's definition. This may be a question about the correct contention for defining interfaces comments in java.
The definition of the RunnableFuture's run() method:
Sets this Future to the result of its computation ...
However, this clearly cannot be always true, since run()'s return type is void, and RunnableFuture is but an interface, it seems that if we were to gaurantee this, we would have to know something about the nature of the implementing class (the get() implementation, for example).
Now, if the RunnableFuture actually returned a value, which was hidden and always returned by an otherwise blocking get() function, such a definition (which would have to occur in a class, rather than an interface, due to its implementation restriction), would clearly be appropriate.
Thus, I am wondering: is the run() method for this interface correctly defined ?
As a counterexample: the Runnable run() interface definition is always correct.
When an object implementing interface Runnable is used to create a
thread, starting the thread causes the object's run method to be
called in that separately executing thread.
Thus, even though Runnable defines no implementation - the interface tells us how the JVM implements threads via the Runnable interface, without unnecessarily imposing non-gauranteed contract on implementing classes.
So I have 3 questions:
Is the documentation for RunnableFuture capable of being incorrect for several cases ?
If (1) is the case, is that acceptable via java conventions?
What is the "real" difference between a RunnableFuture run() and a Runnable run(), if any ?
See http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html
The contract of RunnableFuture is implemented by FutureTask. When you create a FutureTask, you provide either a Callable or a Runnable and a value. The run method of FutureTask looks something like:
public void run() {
V result;
try {
if(callable) {
result = callable.call();
} else {
runnable.run();
result = value;
}
} catch (Throwable t) {
setException(t);
return;
}
set(result);
}
Except the actual implementation wraps the Runnable-value pair in a Callable and does some extra checks to ensure the FutureTask is in the correct state before run is invoked.
Related
I'm building a program that requires the construction of some objects that require such intense computation to create, my smartest course would be to have them built in their own dedicated threads, while the master thread keeps grinding away on other things until the objects are needed.
So I thought about creating a special class specifically designed to create custom objects in their own thread. Like so:
public abstract class DedicatedThreadBuilder<T> {
private T object;
public DedicatedThreadBuilder() {
DedicatedThread dt = new DedicatedThread(this);
dt.start();
}
private void setObject(T i) {
object = i;
}
protected abstract T constructObject();
public synchronized T getObject() {
return object;
}
private class DedicatedThread extends Thread {
private DedicatedThreadBuilder dtb;
public DedicatedThread(DedicatedThreadBuilder builder){
dtb = builder;
}
public void run() {
synchronized(dtb) {
dtb.setObject(dtb.constructObject());
}
}
}
}
My only concern is that this mechanism will only work properly if the master thread (i.e. the thread that constructs the DedicatedThreadBuilder) has a synchronized lock on the DedicatedThreadBuilder until it's construction is completed, and therefore blocks the DedicatedThread's attempt to build the product object until it has finished construction of the DedicatedThreadBuilder. Why? Because the subclasses of DedicatedThreadBuilder will no doubt need to be constructed with parameters the will need to be passed into their own private storage, so that they can be used in the constructObject() process.
e.g.
public class JellybeanStatisticBuilder extends DedicatedThreadBuilder<JellybeanStatistics> {
private int greens;
private int blacks;
private int yellows;
public JellybeanStatisticBuilder(int g, int b, int y) {
super();
greens = g;
blacks = b;
yellows = y;
}
protected JellybeanStatistics constructObject() {
return new JellybeanStatistics(greens, blacks, yellows);
}
}
This will only work properly if the object is blocked to other threads until after it is completely constructed. Otherwise, the DedicatedThread might try to build the object before the necessary variables have been assigned.
So is that how Java works?
I think what you want is to have some sort of synchronised factory class:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
public class SyncFactory<T> {
// alternatively, use newCachedThreadPool or newFixedThreadPool if you want to allow some degree of parallel construction
private ExecutorService executor = Executors.newSingleThreadExecutor();
public Future<T> create() {
return executor.submit(() -> {
return new T();
});
}
}
Now you'd replace usages of T that may need to happen before T is ready with Future<T>, and have a choice between calling its Future.get() method to block until it's ready, set a timeout, or to call Future.isDone() to check up on the construction without blocking. In addition, instead of polling the Future, you may want to have the factory call a callback or post an event to notify the main thread when it has completed construction.
If (big if) this is truly needed (think that one over first)...
The overall idea you are heading toward can work, but your code is confusing and, at first glance by me anyway, appears that it might not work. This type of complexity which can break things is a very good reason to double-think and even triple-think heading down this path.
The major problem I spotted right away is that you are only ever creating 1 instance of the object. If this is a factory which just creates things on another thread, then the DedicatedThread should be called upon in DedicatedThreadBuilder's constructObject, not in its constructor.
If, on the other hand, you actually intend for the DedicatedThreadBuilder to only create 1 instance of T, then this abstraction seems unnecessary... just move DedicatedThread's behavior out to DedicatedThreadBuilder, as DedicatedThreadBuilder doesn't really seem to be doing anything extra.
Second, a minor thing that isn't incorrect so much as it is just unnecessary: you have an inner class which you pass an instance of the outer class to its constructor (that is, DedicatedThread's constructor takes a reference to its parent DedicatedThreadBuilder). This is unnecessary, as non-static inner classes are already linked to their outer classes, so the inner class can reference the outer class without any extra reference to it.
Third, if you move the behavior out of the constructor and into a separate method, then you could synchronize that. Personally, I would have had the constructObject be the thing that kicked off the process, so that calling dtb.constructObject() started the object's creation, and constructObject itself set object = newlyCreatedThing when it was done. Then you could synchronize that method if you want, or do whatever, and not have to worry about the constructor possibly not behaving how you want - in my opinion you should not generally have to worry that a constructor might have some odd side effects.
Fourth, do you have any way to know when the object is ready and available for getting? You might want to add some mechanism for that, such as an observer or other callback.
The problem is that you are using the subclass before it is constructed. It doesn't really have anything to do with multithreading. If you were calling constructObject directly from the DedicatedThreadBuilder constructor, it would be just as bad.
The reasonable implementation that is closet to what you have is just to provide DedicatedThreadBuidler with a separate start() method that should be called after the object is constructed.
Or you could have it extend Thread and use the Thread methods.
Or you could have it implement Runnable so you could use it with a Thread or an Executor or whatever.
I have a list of runnables that I would like to call using lambda expressions:
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(r->r.run());
Is there a 'better' (more efficient) shortcut to call the Runnables run() method other than the following way?
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(Runnable::run);
I think this expression will be translated to a Runnable wrapping the runnable instance in the list.
EDIT:
My assumption/concern (maybe wrong) is that the compiler will translate the expression list.forEach(Runnable::run) to something like this, and thus not 'efficient':
list.forEach(r -> new Runnable() {
#Override
public void run() {
r.run();
}
});
Whether you write
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(r->r.run());
or
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(Runnable::run);
in either case, there will be an instance of Consumer generated, as that’s what Iterable.forEach expects.
The consumer will be equivalent to
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(new Consumer<Runnable>() {
public void accept(Runnable r) {
r.run();
}
});
but that’s not a wrapper around a runnable, as it encapsulates an action applied to arbitrary Runnable instances passed in as parameter. Hence, there is at most one Consumer instance created for the entire forEach operation.
As explained in this answer, the JVM will be responsible for the creation of the Consumer instance and has the freedom to reuse existing instances, which happens in practice with the current implementation and non-capturing instances of functional interfaces, which applies to both variants, using a lambda expression or a method reference, so there will be only one Consumer instance, reused even on subsequent evaluations of the statement.
The only difference with current compilers is that the lambda expression r->r.run() will generate a method within your class calling the run() method whereas for the method reference, the runtime generated Consumer implementation class will call it directly, which makes the method reference more efficient on the hard-to-ever-measure scale.
Exploring the classes in guava to understand the benefits what guava brings, even though with the introduction of java 8, it does not matter that much now, but I am still wondering about how listenableFuture is introduced.
in AbstractListeningExecutorService, there is code snippet like this:
#Override
public ListenableFuture<?> submit(Runnable task) {
return (ListenableFuture<?>) super.submit(task);
}
here super indicates the super class of AbstractListeningExecutorService, namely ExecutorService, but how can we just cast a superclass (Future) to a subclass (ListenableFuture) like this ?
You'll notice the direct superclass of AbstractListeningExecutorService is AbstractExecutorService which
Provides default implementations of ExecutorService execution methods.
This class implements the submit, invokeAny and invokeAll methods
using a RunnableFuture returned by newTaskFor, which defaults to the
FutureTask class provided in this package.
That default is overriden in AbstractListeningExecutorService
Abstract ListeningExecutorService implementation that creates
ListenableFuture instances for each Runnable and Callable submitted to
it
You can also see that in the source code you linked to
/** #since 19.0 (present with return type {#code ListenableFutureTask} since 14.0) */
#Override
protected final <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return TrustedListenableFutureTask.create(runnable, value);
}
That create returns a TrustedListenableFutureTask value, which is a subtype of ListenableFuture.
Those methods in AbstractListeningExecutorService are redeclared so that their return type can be made more specific, ie. ListenableFuture.
Since super.submit(..) has a return type of Future, the return value must be cast to the appropriate subtype, ie. ListenableFuture in this case. And since all calls return the instance created by newTaskFor, it is known that they will be instances of type ListenableFuture. The cast is therefore safe.
Just found a strange and interesting Lambda behavior.
Let's have the following class:
private class Task implements Runnable {
#Override
public void run() {
// something to process
}
}
The following statement is compiling and running:
Callable task = Task::new;
Could somebody explain why this is possible ?
EDIT:
Based on answers below, check the following statements:
1.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(Task::new);
2.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new Task());
On the first glance, seems the same, but actually does a totally different thing.
What happens here is exactly the above situation.
The reason is that ExecutorService has two methods:
submit(Runnable);
submit(Callable);
So, using the code from 1. the executor will process the following on it's internal thread:
new Task()
The version from 2. will actually call the submit(Runnable) method and the code from Task.run will be executed.
Conclusion: just be careful with Lambdas :)
The Callable is not initialized with a Runnable instance, it is initialized with a method reference to the Task constructor that will produce a Runnable when executed.
In other words, if you execute that Callable, it will return a new Task object that has not yet been run. That Task implements Runnable is actually completely irrelevant here.
This would be clearer if you didn't use the raw type. Task::new can be assigned to Callable<Task> because it is something that takes no parameters and returns a Task.
To implement the Callable<V> interface one must implement a method with the signature V call().
Therefore, you can implement this interface with method references of any methods that take nothing and return some reference type, which includes constructor method references such as Task::new.
In fact, any class having a parameter-less constructor can be used this way:
Callable<SomeClass> callable = SomeClass::new;
I'm looking for something that's similar to implementing the java.lang.AutoCloseable interface, where a compiler warning indicating Resource leak: 'xxxx' is never closed is generated.
The use case for this is in a wrapper around a Synchronized Collection in java. The wrapper has an internal semaphore to prevent concurrent modification of the collection.
It allows atomic operations on the collection, in which case the semaphore is acquired and released internally. It also allows the lock to be acquired externally, providing a unique key with which operations can be executed on the collection. The key must be released at the end of the "transaction".
My goal is to create a compiler warning when the lock is acquired and not released within the same method, to prevent deadlock. An alternative design solution that would prevent this is also acceptable.
It's kind of a fun little problem, so I appreciate any insight into it.
As you said
An alternative design solution that would prevent this is also acceptable.
So here it is: As an alternative design solution, use Functional Programming.
Instead of finding out about the error, why not prevent the error from happening in the first place?
Lacking your source code, I make a few assumptions about your code:
Semaphore is your class (or interface) that provides the semaphore to your SynchronizedCollection.
Semaphore provides two methods obtain() and release().
The problem that you're actually facing is a problem of State resp. Change of State which leads to Temporal Coupling. obtain() and release() must be called in order. You can use elements from Functional Programming as an alternative design.
The Semaphore would currently look like this:
public class Sempahore {
// ...
public void obtain() {
// Lock code
}
public void release() {
// Release code
}
}
The Semaphore user would currently look like this:
semaphore.obtain();
// Code protected by the Sempahore.
semaphore.release();
The solution is to combine obtain() and release() into a single function which takes the code to be protected as its argument. This technique is also known as Passing a Block, or more formally as a higher order function - a function that takes another function as an argument or returns another function.
Java also has function pointers, not directly, but indirectly, via references to interfaces. Since Java 8, an interface that has only one abstract method is even called Functional Interface, and Java 8 provides an optional annotation #FunctionalInterface for that.
So, your class Sempahore could instead look like this:
public class Semaphore {
// ...
private void obtain() {
// Lock code
}
private void release() {
// Release code
}
public <V> void protect(final Callable<V> c) throws Exception {
obtain();
try {
return c.call();
} finally {
release();
}
}
}
And the caller would look like this, in Java 7 and older:
semaphore.protect(new Callable<Object>() {
public Object call() {
// Code protected by the Semaphore.
}
});
In Java 8 and newer, the code could also look like this:
semaphore.protect(() -> {
// Code protected by the Semaphore.
});
Quirks about this solution
There's one aspect about Java which sucks completely in this context: Exception Handling. With functional programming, there is urgent need to fix that, but Oracle didn't. I'm still hoping for Java 9, but that won't help all that broken API like java.util.stream that's already out there in the wild. Java 8 still maintains the handle-or-declare-rule of checked exceptions, but functional programming does not take that into account nicely.
There are a few workarounds for that:
Use Runnable, if you do not need return values.
Use your own Callable interface which declares a type parameter for exceptions.
I bet using Runnable is straight-forward and self-explanatory, therefore I won't elaborate on that.
Using your own version of the Callable interface would look like this:
public interface ProtectedCode<V,E> {
V call() throws E;
}
public class Semaphore {
// ...
private void obtain() {
// Lock code
}
private void release() {
// Release code
}
public <V, E> void protect(final ProtectedCode<V, E> c) throws E {
obtain();
try {
return c.call();
} finally {
release();
}
}
}
Now you don't need to mess around with Exception as long as the limited (because it can reflect only one type, not a type set) type inference for type parameter E leads to reasonable results in the compiler.
If you want to be extraordinarily friendly to your users, you could actually offer three variants of the protect method:
public void protect(final Runnable r)
public <V> V protect(final Callable<V> c) throws Exception
public <V,E> V protect(final ProtectedCode<V,E> c) throws E
In order to create compiler warnings, you will need to extend the Eclipse compiler.
An alternative solution was to create a custom check in a software quality analysis system such as Teamscale or SonarQube. The custom checks perform a static analysis of the code (usually based on the abstract syntax tree enriched with semantic information) and create issues whey they detect dodgy code. The issues are displayed on the user interface of the quality analysis system. Eclipse plugins allow an integration of the systems in Eclipse so that the issues can be listed there as well.
While #Christian Hujer did provide a solid solution, I chose to go another route which has been working out well.
There is a wrapper class "Resource" around the SynchronizedCollection which contains:
A semaphore for locking the collection
A randomly generated ID representing the key to the currently held lock
Methods for performing atomic operations on the collection (They acquire the lock, perform the operation, and immediately release it)
Methods for performing non-atomic operations on the collection (They accept an ID as the key and perform the requested operation if the provided key matches the key currently holding the lock)
The class described above is enough to provide sufficient protection around the collection, but what I wanted was compiler warnings if the lock wasn't released.
To accomplish this, there is a "ResourceManager" which implements java.lang.AutoCloseable
This class:
Is passed a reference to the "Resource" via the constructor
Acquires the lock for the reference in the constructor
Provides an API for calling the non-atomic methods on the "Resource" using the key it acquired during construction
Provides a close() method, overriding java.lang.AutoCloseable, which releases the lock acquired during construction
The resource manager is created wherever multiple operations need to be performed on the Resource and a compiler warning is generated if close() is not called on any particular code path. Additionally, in java 7+, the manager can be created in a try-with-resource block and the lock is automatically released, regardless of what happens in the block.