Java 8

ForEach Method

  • Java eight for each method is a utility function to it over a collection, such as list, set or map and stream.
  • It is used to perform a given action on each of the element of the collection.

Meta Space

  • Meta space Help us define process size.
  • If meter space is not handled properly, it may bring down entire application and application server.
  • Meta space was earlier called as PermGen space and was replaced in JDK8.
  • The metadata data is now stored in a native memory called as “Meta space”.
    • This memory is not a contagious Java Heap memory. It allows for improvements over Perm Gen Space in garbage collection, tuning, concurrent de allocation of meta data.
  • Objects are created in eden space in heap memory.
  • If objects survive garbage collection, then they are moved either in Survivor 1, one or survivor 2 space.
  • If the objects survive another garbage collection, then they move to old generation space.
  • Eden space, survival space 1, survival space 2 And old generation space are called in heap Space.
  • Metadata space Takes memory from native memory and all meta data info is stored in meta Space.
  • The advantage of meta space is that we have no more out of memory error Due to Perm Gen space not available.
  • Perm Gen Is a part of Java Heap, Meta space Is not a part of heap. Meta space is a part of Native memory(process manager) Which is only limited by the host operating system.
  • We can configure using -XX: MaxMetaSpace size Which sets the maximum Meta space size for your application.
  • It consumes memory directly from operating system.
  • We also need to monitor meta space along With heap size
Perm Gen
  • Prem Gen is the memory area in heap that is used by JVM to store class and method objects.
  • If our application loads, lots of classes Perm Gen Utilisation will be high.
  • Perm Gen Also stores String intern storage.
  • Size of Perm Gen Is configured using - XX MaxPermSize
  • Typically, 250 6MB should be more than enough for PermGen space for most Of the applications.
  • However, it is not unusual to see the error “java.lang.outofmemoryerror: PermGen Space” If you are loading unusual number of classes.
Lambda Function
  • Earlier we had to create anonymous class to perform a single operation for an object.
  • A separate class needs to be created and loaded every time.
  • Now we can implement our class like a function.
  • Lambda provides us with a concise code.
  • We can change the implementation of an interface to one line by injecting it directly in the object.
  • A lambda expression is used to write a lambda function.
  • Lambda function enables functional programming
  • The code is Readable and concise
  • It is easier to use with API’s and libraries
  • It enabled support for parallel processing
  • We removed the anonymous class and replace it with a functional block of code.
  • We remove the following
    • Name of the function
    • Return type
    • Modifier
  • Lambda expression is a short block of code Which takes in parameters and returns the value.
Streams
Completable Future
  • A Java future API was introduced in Java five and a future is used as a reference to the result of an Asynchronous computation.
    • Future interface was added in Java 5 to serve as a result of asynchronous computation, But it did not have any methods to combine these computations or handle possible errors.
  • In Java, eight, the Completable future class was introduced. Along with the future interface, it also implements The completion stage interface. This interface defines the contract for an Asynchronous computation step that can be combined with other steps.
  • Completable future was introduced as a Java eight concurrency improvement.
  • Completable future Is used for asynchronous programming In Java.
  • Completable future Is at the Same time, a building block and a framework with different methods for composing, combining, Executing a computation steps and handling errors.
  • Completable future class implement the future interface, so you can use it as a future implementation, but with additional completion logic.
  • We can create an instance of this class with a no-arg constructor To present some future result, hand it out to the consumers and complete it at sometime in the future using complete method.
  • The consumer may use the get method to block the current head until this result is provided.
  • Writing a non-blocking code by running a task on a separate thread rather than the main application, thread.
  • The main thread will be able to execute other tasks in parallel improving overall performance of program.
  • There are certain limitations of future because of which Completable future Was introduced in Java 8
    • Say we wrote a method that retrieves data from a remote server And choose to run it in a separate thread and return future.
      • If the remote service is down, we cannot complete future manually using the latest data available.
    • Future cannot perform further action until the result is available, and it doesn’t notify to us of its completion.
    • It provides with a get method which is blogged until the result is available.
    • Attaching a call back function is not possible
    • Multiple futures cannot be chained together.
      • Sometimes we will need to execute a long running task, and when the task is done, we need to send its result to another long running task.
    • Multiple futures cannot be combined together
      • Say we have 10 different future that we want to run in parallel and then Run some function after all of them completes.
    • There is no exception handling in future API.
  • All the above limitations create a requirement of Completable future
  • It implements the future and completion stage interfaces and provides a huge set of methods for creating, changing and combining multiple futures. It also has a very comprehensive exception handling Support.
  • We can manually complete a method using complete function.
  • We can use getnow method to Temporarily return a value
    • This helps to avoid blocking our get method
    • It returns a default value, if result is not ready.
  • Static methods, runAsync() And supplyAsync() Allow us to create a Completable future instance out of the runnable and supplier functional types respectively.
  • If we don’t want to return something from task We use runAsync method Which takes the Runnable interface as input.
  • If we want to return some result from background task we make use of supplyAsync Method which allows us to provide instance of a supplier as a lambda expression.
  • Complete future with an encapsulated computation, logic
    • Static methods, runAsync and supplyAsync Allow us to create a Completable future instance Out of runnable and supplier functional types Correspondingly.
    • Both runnable and supplier are functional interface that allow passing their instances as lambda expressions.
    • The runnable interface is the same old interface used in threads And it does not allow to return the value.
    • The supplier interfere is the generic functional interface with a single method that has no arguments and returns a value of parameterised type.
    • Supplier allows to provide an instance of the supplier as a lambda expression that does the calculation and returns the result.
  • Possessing results of a asynchronous, computations
    • The most generic way to process the result of a computation into feed is to use a function.
    • The thenApply Method does exactly that.
      • Access a function instance uses it to process the results and returns of future that holds a value returned by the function.
    • If we do not want to return a value down the future chain, we can use instance of consumer function interface. It is a single method that takes a parameter and returns void.
    • There is a method in Completable interface called as thenAccept Which accepts a consumer and passes with the result of the computation.
      • The final future get call returns The instance of void type
    • If we neither want to accept any computation, nor want to return some value at the end of the chain Then we can pass runnable lambda To thenRun method.
  • Running multiple futures in Parallel
    • When we need to execute multiple futures in parallel, we usually want to wait for all of them to execute and then process combined results.
  • Handling errors
    • For handling error In a chain of asynchronous computation Steps, Throw/catch, idiom had to be adopted in a similar fashion.
    • Instead of catching an exception in a syntax block, the complete future Allows you to handle it in a handle method. This method receives two parameters, a result of a computation(if it finished successfully) and the Exception thrown(If the computation step did not complete normally)
  • Asynchronous Methods
    • API in Completable future class have two additional variants with the associated Post fix.
    • These methods are usually intended for running a corresponding step of Execution in another thread.
    • The methods without the sink post fix run the next execution stage using The same thread.
    • The Async method without the executor argument Runs a step using the common fork/join pool Implementation of executor That is accessed with the fork join pool Common pool method.
    • Async Method with an executive argument, runs a step using the passed executor.
  • To apply call back, we use thenapply, thenaccept and thenrun methods.
    • Thenapply takes input as a function interface
    • Multiple thenapply methods can be chained
    • Thenaccept and thenrun Method are used as a last call back as they do not return. Any result.
    • Thenaccept Returns takes in a consumer and accept results of previous future and return a void.
    • Thenrun method Simply takes a runnable And will execute it when ever previous future is completed.
    • To run, call back in a different thread Use the following variant of above methods
      • thenApplyAsync
      • thenAcceptAsync
      • thenReturnAsync
    • If we are using two methods that return Completable future then result will be of a type Completable future with a nested Completable future.
      • To get a flattened, Completable future From the above I.e top level Completable future Use thenCompose()
      • Then compose is used to combine two futures while one future depends on other.
      • We also have thenAcceptBoth
    • Completable Future AllOf method
      • Execute multiple futures in parallel weights for all of them to finish and then process their combined results
    • Completable Future AnyOf method
      • This returns values when any of the complete future completes.
      • If you have future, that return results of different types then you won’t know the type of your final result
    • Exception handling
      • Exception is not propagated down the chain.
      • It can be handled using then handle method
      • Once exception occurs, chain is broken.
  • Combining Futures
    • The best part of the Completable future API is The ability to combine compatible instances in a chain of computation steps.
    • The result of this changing is itself, a Completable future That allows further chaining and combining.
    • This approach is in functional languages.
  • Example

No comments:

Post a Comment