Hi, I thought all methods in interfaces are public abstract i.e. they
are not implemented in the interface definition but are supposed to be
implemented by the class implementing the interface. So I was
wondering how come the methods for ExecutorService and Executor
interfaces are defined already ( or are they ?? ).
For e.g. how is this code able to call execute() ??
public class RunnableTester
{
public static void main( String[] args )
{
// create and name each runnable
PrintTask task1 = new PrintTask( "thread1" );
PrintTask task2 = new PrintTask( "thread2" );
System.out.println( "Starting threads" );
// create ExecutorService to manage
threads
ExecutorService threadExecutor =
Executors.newFixedThreadPool(2);
// start threads and place in runnable state
threadExecutor.execute( task1 ); // start task1
threadExecutor.execute( task2 ); // start task2
threadExecutor.shutdown(); // shutdown worker threads
System.out.println( "Threads started, main ends\n" );
} // end main
} // end class RunnableTester
I know Executors class returns an ExecutorService but where is the
method execute() implemented ? Similarly where are the methods in
ExecutorService like shutdown() and shutdownnow() implemented ?
Ankur
...
> I know Executors class returns an ExecutorService but where is the
> method execute() implemented ? Similarly where are the methods in
> ExecutorService like shutdown() and shutdownnow() implemented ?
...
Try calling threadExecutor.getClass().getName() after threadExecutor has
been initialized.
You will find that it references an object that is an instance of some
non-abstract class that implements ExecutorService. That class must
provide, or inherit from its superclass, an implementation of each
ExecutorService method.
Patricia
Lew - 13 Dec 2007 03:46 GMT
> ....
>> I know Executors class returns an ExecutorService but where is the
[quoted text clipped - 9 lines]
> provide, or inherit from its superclass, an implementation of each
> ExecutorService method.
This shows one of the great strengths of languages like Java. The variable
'threadExecutor' has the compile-time type 'ExecutorService', meaning that the
compiler will only let it access those public methods. That's the compiler at
work - the code isn't running on any platform yet.
Now you run the program. Even though the compiler only checked for
'ExecutorService' method calls, the object still has a real type, in this case
some sort of 'FixedThreadPool' that the 'Executors' factory knows how to
manufacture. So the method itself is not in the interface type, it's in the
real non-abstract class that Patricia talked about. It's just that the
compiler won't let you do anything with it except the methods the interface
type authorizes.

Signature
Lew
On Wed, 12 Dec 2007 16:49:43 -0800 (PST), ankur
<ankur.a.agarwal@gmail.com> wrote, quoted or indirectly quoted someone
who said :
> how is this code able to call execute() ??
I think you are asking how is it possible to call a method via an
interface reference.
There is somewhere a concrete class that implements the interface and
somehow it gets instantiated. If you have a reference to it, you can
assign that reference to a variable of the interface type. You still
have a real object, not some vaporous object created by divine
intervention out of the interface.
When you then invoke a method of the interface, the JVM checks the
type of the actual object the reference points to and finds the actual
method corresponding to the method name in the Interface, and executes
THAT.
Java has a lot of plug-in code, where the names of the actual classes
are hidden and undocumented. In JCE for example you invoke methods
with Strings and it finds corresponding class files for
implementations of various standard interfaces and instantiates
objects that implement the interfaces.
Another example
URL.openConnection() produces an HttpURLConnection, or sometimes a
netscape.net.URLConnection
it is advertised to produce an URLConnection. URLConnection is a
superclass of HttpURLConnection not an interface, but it is the same
principle.
Another example would be:
Calendar.getInstance. The result is advertised as Calendar, but it
could well give you a subclass GregorianCalendar.
NumberFormat.getInstance in advertised to return a NumberFormat, but
it could just as well give you a subclass DecimalFormat.
I like to know what sorts of object I am dealing with REALLY, even if
I limit myself to the official limited interface. You can find out
with:
System.out.println( xxx.getClass() );
To find out the ACTUAL class of some object.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
ankur - 20 Dec 2007 01:26 GMT
On Dec 14, 9:31 am, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:
> On Wed, 12 Dec 2007 16:49:43 -0800 (PST),ankur
> <ankur.a.agar...@gmail.com> wrote, quoted or indirectly quoted someone
[quoted text clipped - 47 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com
Roedy,
I understand what you are saying. Great Answer!
So the class that implements execute() is ThreadPoolExcecutor. So as I
understand what should be happening in static method
newFixedThreadPool of Executors class:
public static ExecutorService newFixedThreadPool(int nThreads)
{
//Other code
ExecutorService var = new ThreadPoolExecutor(nThreads);
return var;
}
This is because :
public class ThreadPoolExecutor extends AbstractExecutorService
public abstract class AbstractExecutorService extends Object
implements ExecutorService
public interface ExecutorService extends Executor
"So ThreadPoolExecutor is a AbstractExecutorService is a
ExecutorService is a Executor"
So ThreadPoolExecutor is a ExecutorService. (Method execute() for
interface Executor is inherited by ExecutorService).
In Executors class method newFixedThreadPool():
ExecutorService variable holds ThreadPoolExecutor object and when
ExecutorService variable calls execute() it is called for the
ThreadPoolExecutor object ( and ExecutorService variable knows execute
because it inherits it from Execute).
This is similar to defining an abstract super class with all the
methods and a number of concrete classes extending the Abstract class.
This way correct method for the subclass object is called correctly
whenever subclass object is assigned to superclass variable ! Thats
how Polymorphic behavior is implemented !!!