2. Agenda
Fork and Join Framework
New File System API(NIO 2.0)
Asynchronous I/O
Custom File System Provider
Dynamic Language Support
The try-with resources Statement
Improved Exception Handling
Other improvements
Underscores in Numeric Literals
String in switch Statement
Diamond Operator
3. Fork and Join
Fork/Join framework is an implementation of
ExecutorService interface.
Helps to take advantage of multiple processors.
It is designed for work that can be broken into smaller pieces
recursively.
The goal is to use all the available processing power to make
application wicked fast.
Fork/Join framework distributes tasks to worker threads in a
thread pool.
It uses a work-stealing algorithm
Worker threads that run out of things to do can steal tasks
from other threads that are still busy
5. Fork and Join
Works on "divide and conquer" algorithm
Also referred to as "map and reduce"
Map Phase : Splitting the data space to be processed
by an algorithm into smaller, independent chunks.
Reduce Phase : Collection of partial results to form
the final result once a set of chunks has been
processed.
6. Fork and Join
Basic Use
if (my portion of the work is small enough)
do the work directly
else
split my work into two pieces
invoke the two pieces and wait for the results
8. Fork and Join
Important Classes
ForkJoinPool - An ExecutorService for running
ForkJoinTasks.
ForJoinTask - Abstract base class for tasks that run
within a ForkJoinPool
RecursiveAction : A recursive resultless ForkJoinTask
RecursiveTask : A recursive result-bearing ForkJoinTask.
9. Fork and Join
Typical Steps :
Partition into subproblems - Break up main problem into
several parts. Each part should be as independent as
possible.
Create subtasks - Construct each solution to each part as a
ForkJoinTask.
Fork subtasks - Feed subtasks to pool of worker threads.
Base pool size on number of CPUs or other resource
considerations.
Join subtasks - Wait out processing of as many
subtasks (usually all) needed to compose solution
Compose solution - Compose overall solution from
completed partial solutions.
10. Fork and Join
Some Facts
Different kind of tasks
Computation-intensive
I/O-intensive
Event-intensive
Most useful with Computation-intensive tasks
Normally best to have one worker thread per CPU
Each new task is queued in current worker thread’s dequeue (double-
ended queue)
Workers run tasks from their own dequeues in stack-based LIFO (i.e.,
newest task first) order.
If a worker is idle, it steals a task, in FIFO (oldest task first) order from
another thread’s dequeue or entry queue
12. New file system API (NIO 2.0)
New package java.nio.file to access files, file attributes and file
systems.
New classes to ease life of developer when working with multiple
file systems.
Path
Paths
FileSystem
FileSystems
Files
13. New file system API (NIO 2.0)
File I/O Methods Arranged from Less Complex to More
Complex
14. New file system API (NIO 2.0)
OpenOptions Parameters
WRITE – Opens the file for write access.
APPEND – Appends the new data to the end of the file. This option is used with the WRITE or
CREATE options.
TRUNCATE_EXISTING – Truncates the file to zero bytes. This option is used with the WRITE
option.
CREATE_NEW – Creates a new file and throws an exception if the file already exists.
CREATE – Opens the file if it exists or creates a new file if it does not.
DELETE_ON_CLOSE – Deletes the file when the stream is closed. This option is useful for
temporary files.
SPARSE – Hints that a newly created file will be sparse. This advanced option is honored on
some file systems, such as NTFS, where large files with data "gaps" can be stored in a
more efficient manner where those empty gaps do not consume disk space.
Example :
Path path = Paths.get("file.txt")
OutputStream out = Files.newOutputStream(path, CREATE, APPEND);
15. New file system API (NIO 2.0)
File Creation supports optional set of initial attributes. e.g.
For UNIX based file system one can specify
Owner
Group Owner
File permissions at the time file is created.
16. New file system API (NIO 2.0)
Reading All Bytes or Lines from a File
readAllBytes(Path)
readAllLines(Path, Charset)
Path file = Paths.get("c:Tempxyz.txt");
byte[] fileArray = Files.readAllBytes(file);
Writing All Bytes or Lines to a File
write(Path, byte[], OpenOption...)
write(Path, Iterable< extends CharSequence>, Charset, OpenOption...)
Path file = Paths.get("c:Tempxyz.txt");
byte[] buf = ...;
Files.write(file, buf);
18. New file system API (NIO 2.0)
Creating Temporary Files
One of the following methods can be used
Files.createTempFile(Path dir,String prefix,String suffix,FileAttribute<?>... attrs)
Allows to specify the directory in which temporary file will be created.
Files.createTempFile(String prefix,String suffix,FileAttribute<?>... attrs)
Creates new file in default temporary file directory.
***********************************************************************************************
try {
Path tempFile = Files.createTempFile(null, ".myapp");
System.out.format("The temporary file has been created: %s%n", tempFile)
;
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
************************************************************************************************
Result
The temporary file has been created: /tmp/509668702974537184.myapp
19. New file system API (NIO 2.0)
Reading a File by Using Buffered Stream I/O
BufferedReader reader = Files.newBufferedReader(path, charset)
Writing a File by Using Buffered Stream I/O
BufferedWriter writer = Files.newBufferedWriter(path, charset)
Similar methods exists for InputStream and OutputStream
InputStream in = Files.newInputStream(path)
OutputStream os = Files.newOutputStream(path)
20. New file system API (NIO 2.0)
Access Control Lists(ACL)
Adds entry to existing ACL to grant "joe" access
21. New file system API (NIO 2.0)
Managing Metadata
size(Path) - Returns the size of the specified file in bytes.
isDirectory(Path, LinkOption) - Returns true if the specified Path locates a file that is a
directory.
isRegularFile(Path, LinkOption...) - Returns true if the specified Path locates a file that is a
regular file.
isSymbolicLink(Path) - Returns true if the specified Path locates a file that is a symbolic link.
isHidden(Path) - Returns true if the specified Path locates a file that is considered hidden
by the file system.
getLastModifiedTime(Path, LinkOption...) / setLastModifiedTime(Path, FileTime) - Returns
or sets the specified file's last modified time.
getOwner(Path, LinkOption...) / setOwner(Path, UserPrincipal) - Returns or sets the owner
of the file.
getPosixFilePermissions(Path, LinkOption...) / setPosixFilePermissions(Path,
Set<PosixFilePermission>) - Returns or sets a file's POSIX file permissions.
getAttribute(Path, String, LinkOption...) / setAttribute(Path, String, Object, LinkOption...)
- Returns or sets the value of a file attribute.
22. New file system API (NIO 2.0)
File change notifications
WatchService API – To receive notification events
upon changes to the subject (directory or file).
Create a WatchService. This service consists of a queue to
hold WatchKeys
Register the directory/file you wish to monitor with this
WatchService
While registering, specify the types of events to receive
(create, modify or delete events)
Start an infinite loop to listen to events
When an event occurs, a WatchKey is placed into the
queue
Consume the WatchKey and invoke queries on it
23. Asynchronous I/O
Asynchronous I/O API for both sockets and files.
Asynchronous channel represent a connection that
supports nonblocking operations e.g connecting,
reading or writing.
Provides mechanisms for controlling the operations after
they have been initiated.
Future Style – Initiate I/O operation, returning
java.util.concurrent.Future
Callback Style – Specify CompletionHandler when
invoking I/O operation. CompletionHandler invoked
when I/O operation completes.
28. Asynchronous I/O
Asynchronous Channel Groups
Each asynchronous channel constructed belongs to a channel group that
shares a pool of Java threads.
They are used for handling the completion of initiated asynchronous I/O
operations.
By default, channels constructed with the open() methods belong to a
global channel group.
That can be configured using the following system variables:
java.nio.channels.DefaultThreadPoolthreadFactory - defines a
java.util.concurrent.ThreadFactory to use instead of the default one
java.nio.channels.DefaultThreadPool.initialSize - specifies the thread
pool's initial size
29. Asynchronous I/O
Three utility methods in java.nio.channels.AsynchronousChannelGroup
provide a way to create new channel groups:
withCachedThreadPool()
withFixedThreadPool()
withThreadPool()
30. Custom File System Provider
The NIO 2.0 API provides the ability to develop a custom file
system provider.
A file system is essentially a container with organized,
homogenous elements referred to as file system objects
A file system provides access to file system objects.
A file system object can be a
File store
File
Directory
31. Custom File System Provider
A file store is a volume or partition in which files are stored
For e.g in Windows, C: and D: are file stores
On the Solaris operating system, / (root) and mounted directories
are considered file stores.
The java.nio.file.spi.FileSystemProvider class allows you to
develop a custom file system provider
32. Custom File System Provider
A custom file system provider is useful in the following situations
Developing a memory-based or zip-file-based file
system
Developing a fault-tolerant distributed file
system(Data Striping and Replication for high
performace and to maintain data integrity)
Replacing or supplementing the default file system
provider(e.g. logging all system operations and
delegate to the default provider for other routine
operations)
33. Custom File System Provider
Implementing Custom File System Provider
Create a custom file system provider class that extends the
java.nio.file.spi.FileSystemProvider class.
Define a URI scheme (e.g file, jar, memory) for the file system
provider. The getScheme method should return the URI scheme
of this provider.
Create an internal cache to keep track of file systems created by this
provider.
Implement the newFileSystem method.
Implement the getFileSystem method.
Implement the newFileChannel method or the
newAsynchronousFileChannel method. This method should return
a FileChannel object that allows a file to be read or written in the
file system.
34. Dynamic Language Support
New Java bytecode "invokedynamic" has been added
Accompanying linkage mechanism that involves a new construct
called a "Method Handle".
Dynamic Language Compilers can use this new bytecode
Dynamic Language should run faster on JVM
35. Dynamic Language Support
What is "Dynamic Language"
A class of high level programming language that
execute at run time many common behaviours that
static languages perform during compilation.
Behaviour such as extension of the program by
Adding new code
Extending objects and definitions
Modifying type sytem
E.g Groovy, JRuby, Jython etc.
36. Dynamic Language Support
The Challenge of Compiling Dynamically Typed Languages
Example to add two numbers
def addtwo(a, b)
a + b;
end
Statically Typed Language Compliler chooses implementation of "+" based on
static types of a and b(iadd for integer)
Dyanmically Typed Language Compiler must differ the choice until run time.
The statement a + b is compiled as the method call +(a, b), where "+" is the
method name
The types of a and b will be determined at run time and accordingly the
implementation of "+" will be called.
37. Dynamic Language Support
Current Problem
Bytecode instructions for Method invocation
invokevirtual : Invokes a method on a class.
invokeinterface - Invokes a method on an interface
invokestatic - Invokes a static method on a class.
invokespecial - Invokes a method without reference to the
type of the receive e.g constructors, superclass methods
or private methods.
38. Dynamic Language Support
Java Code
String s = "Hello World";
System.out.println(s);
Bytecode
ldc #2 // Push the String "Hello World" onto the stack
astore_1 // Pop the value "Hello World" from the stack and store it in local variable #1
getstatic #3 // Get the static field java/lang/System.out:Ljava/io/PrintStream from the class
aload_1 // Load the String referenced from local variable #1
invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
39. Dynamic Language Support
Different ways to handle
Create language-specific Java types for the return
value and method arguments, especially those
which act as method call receivers
Use java.lang.reflect.Method to invoke method
Create a language-specific interpreter for method
invocation to run on top of the JVM.
40. Dynamic Language Support
Invokedynamic – New Bytecode instruction
MethodHandle – Direct executable reference to an underlying
method, constructor, field, or similar low-level operation, with
optional transformations of arguments or return values
CallSite – Holder for MethodHandle, which is called its target. An
invokedynamic instruction linked to a CallSite delegates all calls
to the site's current target.
Bootstrap Method - This method links the name specified by the
invokedynamic instruction with the code that should be
executed (the target method), which is referenced by a method
handle.
41. Dynamic Language Support
The invokedynamic instruction
Simplifies and improves implementations of compilers and
runtime systems for dynamic languages on the JVM
Each instance of invokedynamic instruction is called a
dynamic call site.
A dynamic call site is originally in an unlinked state. i.e there is
no method for call site to invoke.
It is linked to a method by means of a bootstrap method
Bootstrap method is specified by the compiler for the
dynamically-typed language that is called once by the JVM
to link the site
The object returned from the bootstrap method permanently
determines the call site's behavior
42. Dynamic Language Support
Example
IntegerOps class belongs to the library that
accompanies the dynamic language's runtime
system.
The method Bootstrap.mybsm is a bootstrap method
that links the invokedynamic call site to the adder
method.
The object callerClass is a lookup object, which is a
factory for creating method handles.
The method MethodHandles.Lookup.findStatic (called
from the callerClass lookup object) creates a static
method handle for the method adder.
44. The try-with-resources Statement
Is a try statement that declares one or more resources
A resource is as an object that must be closed after the program is
finished with it.
It ensures that each resource is closed at the end of the
statement.
Any object that implements java.lang.AutoCloseable can be used
as a resource.
E.g
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
45. The try-with-resources Statement
Declaring multiple resources
try (
java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
){
//perform work
}
The close methods of resources are called in the
oppositeorder of their creation.
46. The try-with-resources Statement
Can have catch and finally blocks just like an ordinary try
statement
Any catch or finally block is run after the resources declared have
been closed
47. The try-with-resources Statement
Suppressed Exceptions
An exception can be thrown from the block of code associated
with the try-with-resources statement.
In the example writeToFileZipFileContents, an exception can
be thrown from the try block, and up to two exceptions can
be thrown from the try-with-resources statement when it tries
to close the ZipFile and BufferedWriter objects.
Suppressed exceptions can be retrieved by calling the
Throwable.getSuppressed method from the exception
thrown by the try block.
48. Improved Exception Handling
Handing more than one type of Exception
Before Java 7
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
In Java 7
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
49. Improved Exception Handling
Rethrowing Exceptions with More Inclusive Type Checking
Before Java 7
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName) throws Exception {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e;
}
}
51. Underscores in Numeric Literals
Any number of underscore characters (_) can appear anywhere
between digits in a numerical literal
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
52. Underscores in Numeric Literals
Allowed only between digits
Not allowed
At the beginning or end of a number
Adjacent to a decimal point in a floating point literal
Prior to an F or L suffix
In positions where a string of digits is expected
float pi1 = 3_.1415F; // Invalid; cannot put underscores adjacent to a decimal point
float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point
int x1 = _52; // This is an identifier, not a numeric literal
int x3 = 52_; // Invalid; cannot put underscores at the end of a literal
53. String in switch Statement
The switch statement compares the String object using the
String.equals method
Consequently the comparison is case sensitive
The Java compiler generates generally more efficient bytecode
from switch statements that use String objects than from
chained if-then-else statements.
54. Diamond Operator(<>)
Type declaration is not required on right side
Before Java 7
Map<String, List<Trade>> trades = new TreeMap<String, List<Trade>> ();
In Java 7
Map<String, List<Trade>> trades = new TreeMap <> ();