Friday, January 31, 2020

What is happens-before in Java Concurrency? An example

Java Concurrency, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep

A couple of days ago, one of my readers messaged me on LinkedIn about a Java interview question he has recently faced - what is the happens-before relationship in Java concurrency? What is the benefit of it, and how exactly it works? He kind of has some ideas about that its related to the Java Memory Model and provides some sort of visibility guaranteed but couldn't explain with conviction to his interviewer, particularly with a code example and was a bit disappointed. He then asked me if I can write an article about it. I said you should have read the Java concurrency in Practice book before the interview, that would have helped, but nonetheless, I liked the idea to just provide a quick overview of what is the happens-before relationship between threads in Java.

To understand the happens-before relationship, you need to first understand what problems can occur if the same variable is accessed by multiple threads? particularly if one thread writes into the variable, and one thread read from it at the same time.

For example, let's say we have the following code, which is executed by Thread T1, (note, integer variable y is initialized before x)

int y = 1;
int x = 2;

Now, we have another piece of code which is executed by another thread T2 where the value of both the variable is printed (note variable x is printed before y) :

System.out.print(x);
System.out.println(y);

What do you think? What should be printed on the screen? If this code is executed by the same thread, then it's guaranteed that 2 and 1 will be printed, but with multiple threads, there is no guaranteed behavior. It's entirely possible that T2 could not see the assignments made by T1 and just print 0 for both x and y.

It's also possible that it can just see the initialization of either x or y and print accordingly.

This is scary and unpredictable, think what will happen if X is money in your bank account, you definitely want a predictable behavior.

That's where happens-before comes into play. It provides some sort of ordering and visibility guarantee. There is a lot of rule concerning Happens-before (which you can read on Java Concurrency in Practice). Still,  the most important one is if there is a synchronization like a synchronized block or a volatile variable then.

- "A volatile write will happen before another volatile read."
- "An unlock on the synchronized block will happen before another lock."

And, (this is most important)

All the changes which are visible to T1 before a volatile write or a synchronized unlock will be visible to thread T2 after a volatile read of the same variable or locking on the same monitor.

This statement is the most important one, and it can be best understood by the following diagram:

Java Concurrency, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep
Image credit - Java Concurrency in Practice

You can see that before unlock, thread T1 can see y=1 and x=1, so after T2 gets a lock on the same object, it can also see y=1 and x=1, even though y is not a volatile variable or read inside the lock or synchronized context. This is also true for volatile write and volatile read, which offers slightly less form of synchronization but a great alternative when it comes to visibility.

Now, let's go back to our example if we modify our code like this:

T1:
int y = 1;
volatile int x = 2;

T2:
System.out.print(x);
System.out.println(y)

What do you think? What does the code print now? 2 and 1 or 2 and 0?

Well, if you apply the happens-before than when T1 does a volatile write, and T2 does a volatile read, then it will also see the value of y=1, which is not volatile. Isn't behavior is now more predictable.

The critical thing to remember here is that even the value of a non-volatile variable is visible to thread T2. This is just one example of a happens-before relationship but very useful in analyzing the behavior of a multi-threaded program.

If you are serious about improving your understanding of Java concurrency knowledge and skills, I strongly suggest you should read the Java Concurrency in Practice book by Brian Goetz, Joshua Bloch, Doug Lea and team, one of the best resources for Java developers.

Java Concurrency, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep

Thursday, January 30, 2020

Difference between SendRedirect() and Forward() in JSP Servlet

Java SendRedirect(), Java Forward(), JSP Servlet, Oracle Java Tutorial and Material

Difference between SendRedirect and forward is one of classical interview questions asked during java web developer interview. This is not just applicable for servlet but also for JSP in which we can use forward action or call sendRedirect() method from scriptlet. Before examining difference on forward and SendRedirect let’s see what send Redirect method and forward method does.

SendRedirect (): 

This method is declared in HttpServletResponse Interface.

Signature: void sendRedirect(String url)

This method is used to redirect client request to some other location for further processing ,the new location is available on different server or different context.our web container handle this and transfer the request using  browser ,and this request is visible in browser as a new request. Some time this is also called as client side redirect.

Forward():

This method is declared in RequestDispatcher Interface.

Signature: forward(ServletRequest request, ServletResponse response)
This method is used to pass the request to another resource for further processing within the same server, another resource could be any servlet, jsp page any kind of file.This process is taken care by web container when we call forward method request is sent to another resource without the client being informed, which resource will handle the request it has been mention on requestDispatcher object which we can get by two ways either using ServletContext or Request. This is also called server side redirect.

RequestDispatcher rd = request.getRequestDispatcher("pathToResource");
  rd.forward(request, response);

Or

RequestDispatcher rd = servletContext.getRequestDispatcher("/pathToResource");
  rd.forward(request, response);

Difference between SendRedirect and Forward


Now let’s see some difference between these two method of servlet API in tabular format.

Forward() SendRediret() 
When we use forward method request is transfer to other resource within the same server for further processing. In case of sendRedirect request is transfer to another resource to different domain or different server for futher processing.
In case of forward Web container handle all process internally and client or browser is not involved.  When you use SendRedirect container transfers the request to client or browser so url given inside the sendRedirect method is visible as a new request to the client.
When forward is called on requestdispather object we pass request and response object so our old request object is present on new resource which is going to process our request In case of SendRedirect call old request and response object is lost because it’s treated as new request by the browser.
Visually we are not able to see the forwarded address, its is transparent In address bar we are able to see the new redirected address it’s not transparent.
Using forward () method is faster then send redirect.  
SendRedirect is slower because one extra round trip is required beasue completely new request is created and old request object is lost.Two browser request requird.
When we redirect using forward and we want to use same data in new resource we can use request.setAttribute () as we have request object available. But in sendRedirect if we want to use we have to store the data in session or pass along with the URL.

Example of forward and SendRedirect in JSP Servlet:


Any kind of online payment when we use merchant site will redirect us to net banking site which is completely new request it process our request and again redirect to merchant site?

In Banking Application when we do login normally we use forward method. In case of online banking we are asked for username and password if it’s a correct some another servlet or resource will handle the request other wise request has been forwarded to error page.

Which one is good?


Its depends upon the scenario that which method is more useful.

If you want control is transfer to new server or context and it is treated as completely new task then we go for Send Redirect.
 
Normally forward should be used if the operation can be safely repeated upon a browser reload of the web page will not affect the result.

SendRedirect and forward method are still very useful while programming or working on any web application project using servlet jsp. This is still a popular interview questions so don’t forget to revise forward and sendRedirect before appearing for any job interview.

Wednesday, January 29, 2020

Difference between JRE JVM and JDK in Java Programming language

JRE JVM and JDK, Oracle Study Materials, Oracle Learning, Oracle Guides, Oracle Certification

JRE, JVM, and JDK are three terms you often heard in conjunction with Java programming language and most people either confuse them or think they all are same. In this java article, we will what is Java Run-time (JRE), what is Java virtual Machine (JVM) and what is Java development Kit (JDK) along with Just in Time compiler or JIT. Once you know what JRE, JVM or JDK means you can differentiate them easily by yourself.

JRE JVM and JDK in Java Programming language


Java Runtime Environment (JRE)

Java is every where in browser, in mobile, in TV or in set-top boxes and if you are into Java programming language than you know that Java code which is bundled in JAR (Java archive) file require Java virtual machine JVM to execute it. Now JVM is an executable or program like any other program and you can install that into your machine. You have seen browser often suggesting download JRE to run a Java Applet downloaded from Internet. Various version of JRE are available in java.oracle.com and most of the user who just want to execute Java program inside browser or standalone downloads JRE. All browsers including Internet Explorer, Firefox and Chrome can work with JRE.

Java Virtual Machine (JVM)

When you download JRE and install on your machine you got all the code required to create JVM. Java Virtual Machine is get created when you run a java program using java command e.g. java HelloWorld. JVM is responsible for converting byte code into machine specific code and that's why you have different JVM for Windows, Linux or Solaris but one JAR can run on all this operating system. Java Virtual machine is at heart of Java programming language and provide several feature to Java programmer including Memory Management and Garbage Collection, Security and other system level services. Java Virtual Machine can be customized e.g we can specify starting memory or maximum memory of heap size located inside JVM at the time of JVM creation. If we supplied invalid argument to java command it may refuse to create Java Virtual Machine by saying "failed to create Java virtual machine: invalid argument". In short Java Virtual Machine or JVM is the one who provides Platform independence to Java.

Java Development Kit (JDK)

JDK is also loosely referred as JRE but its lot more than JRE and it provides all the tools and executable require to compile debug and execute Java Program. Just like JRE, JDK is also platform specific and you need to use separate installer for installing JDK on Linux and Windows. Current Version of JDK is 1.7 which is also referred as Java7 and it contains javac (java compiler) based on programming rules of Java7 and Java which can execute java7 code with new features like String in Switch, fork-join framework or Automatic Resource Management. When you install JDK, installation folder is often referred as JAVA_HOME. All binaries are located inside JAVA_HOME/bin which includes javac, java and other binaries and they must be in your system PATH in order to compile and execute Java programs.

JRE JVM and JDK, Oracle Study Materials, Oracle Learning, Oracle Guides, Oracle Certification

Difference between JRE, JDK and JVM


In short here are few differences between JRE, JDK and JVM:

1)  JRE and JDK come as installer while JVM are bundled with them.

2)  JRE only contain environment to execute java program but doesn’t contain other tool for compiling java program.

3)  JVM comes along with both JDK and JRE and created when you execute Java program by giving “java” command.

Just in Time Compiler (JIT)


Initially Java has been accused of poor performance because it’s both compiles and interpret instruction. Since compilation or Java file to class file is independent of execution of Java program do not confuse. Here compilation word is used for byte code to machine instruction translation. JIT are advanced part of Java Virtual machine which optimize byte code to machine instruction conversion part by compiling similar byte codes at same time and thus reducing overall execution time. JIT is part of Java Virtual Machine and also performs several other optimizations such as in-lining function.

That’s all on JRE, JDK and Java Virtual machine and difference between them. Though they look similar they are different and having a clear idea of JVM, JIT or JDK helps in java programming.

Tuesday, January 28, 2020

Introduction to HTTP/2 support in Java 9

Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certifications

1. Introduction


The IETF streaming group approved the HTTP/2 protocol in 2015, sixteen years after HTTP/1.1 had been released. HTTP/2 comes with the promise of lowering latency and makes many of those workarounds obsolete which were necessary for HTTP/1.1 in order to be able to keep up with today’s response time requirements. In this article, I introduce HTTP/2 briefly and how it renews the text-based HTTP/1.1 and then we look into the upcoming HTTP/2 support in Java 9.

2. Latency optimization techniques for HTTP/1.1


People are getting more and more inpatient on the Internet, but they wouldn’t notice that the actions they’re performing on the web aren’t being performed by themselves directly, if response time if below 100ms.

When response time goes up to 1sec that does get noticed and when it takes longer than 10s for a site to respond, it’s considered to be out of order. According to some research the average attention span has decreased to 7-8 seconds and even a 1sec delay could cause 7% loss in revenue.

HTTP/1.1 has needed (sometimes heavy) workarounds to meet today’s requirements.
  • As one HTTP connection can download one resource at a time, browsers fetch them concurrently in order to be able to render the page faster. However, the number of parallel connections per domain is limited and domain sharding was used to work that around.
  • A similar optimization technique was to combine multiple resources (CSS, JavaScript) into a single bundle in order to be able to get them with a single request. The trade-off is sparing a network round-trip with the risk of not using some parts of the assembled resource bundle at all. In some cases complicated server side logic takes care of selecting the pertinent static resources and merging them for particular page request
  • Image sprites is a technique similar to bundling CSS and JavaScript files for lowering the number of requests.
  • Another technique being is in-lining static resources to the HTML


3. A brief introduction to HTTP/2



HTTP/2 is meant to alleviate the pain stemming from maintaining complex infrastructures for HTTP/1.1 in order to make it perform well. Although HTTP/2 is still backward compatible with HTTP/1.1, it’s not a text based protocol any more. Clients establish a connection as an HTTP/1.1 request and requests and upgrade. From that on, HTTP/2 talks in binary data frames.

3.1. HTTP/2 multiplexing

HTTP/2 multiplexing makes all of the HTTP/1.1 workarounds above obsolete, because a single connection can handle multiple bi-directional streams, thus allowing clients for downloading multiple resources over a single connection simultaneously.

3.2. HTTP/2 header compression

The HTTP 1.x protocols were text-based and thus they were verbose. Sometime the same set of HTTP headers were exchanged all over and over again. HTTP/2 diminishes the required bandwidth drastically by maintaining a HTTP header table across requests. Essentially this is de-duplication and not compression in the classical sense.

3.3. HTTP/2 push

You might think that HTTP/2 push is the continuation or an upgrade of some kind to WebSocket, but it’s not the case. While WebSocket is a means to full-duplex communication between the client and the server in order to allow the server to send data to clients once a TCP connection has been established, HTTP/2 solves a problem separate to that.

HTTP/2 push is about sending resources to clients proactively without having to ask for it from the client’s perspective. This practically means that the server side knows that a website needs some images and it sends them all at once (ahead of time) long before clients requests them.

4. Java HTTP clients supporting HTTP/2


According to one of the Wiki pages of the HTTP/2, at the time of writing the following Java client libraries are available for establishing HTTP/2 connections.

◉ Jetty

◉ Netty

◉ OkHttp

◉ Vert.x

◉ Firefly

In this article however, we’re focusing on the HTTP/2 support provided by Java 9. JEP 110 specifies the requirements and it also states that the project is still in incubation state, which practically means that it’s not going to replace the existing UrlConnection API in java 9.

Only with Java 10 will the standard Java HTTP/2 client be moved under package java.net. In the meantime however, it will live underneath the jdk.incubtor namespace.

5. Explore HTTP/2 Client of Java 9


JEP 110 sets requirements for the new, built-in HTTP/2 client so that it provide a high-level, easy to use API and comparable (or higher) performance than existing alternatives (see above).

The first step is import module jdk.incubator.httpclient.

module com.springui.echo.client {
  requires jdk.incubator.httpclient;
}

For the sake of this example, we’ll be using Undertow as a HTTP/2 compliant web server. It just echoes back that message what clients send to it.

public class EchoServer {

  private static final Logger LOGGER = Logger.getLogger(EchoServer.class.getSimpleName());

  private static final int PORT = 8888;
  private static final String HOST = "localhost";

  public static void main(final String[] args) {
    Undertow server = Undertow.builder()
        .setServerOption(UndertowOptions.ENABLE_HTTP2, true)
        .addHttpListener(PORT, HOST)
        .setHandler(exchange -> {
          LOGGER.info("Client address is: " + exchange.getConnection().getPeerAddress().toString());
          exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
          exchange.getRequestReceiver().receiveFullString((e, m) -> e.getResponseSender().send(m));
        }).build();

    server.start();
  }

}

The new API follows the builder pattern everywhere and HttpClient, which is the entry point of initiating HTTP requests, is no exception to that.

HttpClient client = HttpClient
    .newBuilder()
    .version(Version.HTTP_2)
    .build();

5.1. Sending a request in blocking mode

Once we have an HttpClient instance, HttpRequest instances can also be constructed with a builder.

HttpResponse<String> response = client.send(
    HttpRequest
        .newBuilder(TEST_URI)
        .POST(BodyProcessor.fromString("Hello world"))
        .build(),
    BodyHandler.asString()
);

Method send block as long as the request is being processed, however there’s a way to exchange HTTP messages asynchronously as well.

5.2. Sending requests in non-blocking mode

In the following example 10 random integers get sent to our HTTP echo server asynchronously and when all of the requests have been initiated, the main thread waits for them to be completed.

List<CompletableFuture<String>> responseFutures = new Random()
    .ints(10)
    .mapToObj(String::valueOf)
    .map(message -> client
        .sendAsync(
          HttpRequest.newBuilder(TEST_URI)
            .POST(BodyProcessor.fromString(message))
            .build(),
          BodyHandler.asString()
        )
        .thenApply(r -> r.body())
    )
    .collect(Collectors.toList());

CompletableFuture.allOf(responseFutures.toArray(new CompletableFuture<?>[0])).join();

responseFutures.stream().forEach(future -> {
  LOGGER.info("Async response: " + future.getNow(null));
});

5.3. Processing push-promise frames

All of the examples above could have been normal, old fashioned HTTP/1.1 requests. Apart from creating the HttpClient, nothing HTTP/2 specific can be observed.

Probably the most relevant HTTP/2 feature of the client API is the way it handles multiple responses when HTTP/2 push is used.

Map<HttpRequest, CompletableFuture<HttpResponse<String>>> responses =
  client.sendAsync(
    HttpRequest.newBuilder(TEST_URI)
      .POST(BodyProcessor.fromString(TEST_MESSAGE))
      .build(),
    MultiProcessor.asMap(request -> Optional.of(BodyHandler.asString()))
  ).join();
responses.forEach((request, responseFuture) -> {
  LOGGER.info("Async response: " + responseFuture.getNow(null));
});


Source: javacodegeeks.com

Monday, January 27, 2020

Java Applet

Java Applet, Oracle Java Study Materials, Oracle Java Prep

Applet is a special type of program that is embedded in the webpage to generate the dynamic content. It runs inside the browser and works at client side.

Advantage of Applet


There are many advantages of applet. They are as follows:

- It works at client side so less response time.

- Secured

- It can be executed by browsers running under many plateforms, including Linux, Windows, Mac Os etc.


Drawback of Applet



- Plugin is required at client browser to execute applet.

Hierarchy of Applet


Java Applet, Oracle Java Study Materials, Oracle Java Prep

As displayed in the above diagram, Applet class extends Panel. Panel class extends Container which is the subclass of Component.


Lifecycle of Java Applet


1.Applet is initialized.

2. Applet is started.

3. Applet is painted.

4. Applet is stopped.

5. Applet is destroyed.

Java Applet, Oracle Java Study Materials, Oracle Java Prep

Lifecycle methods for Applet:


The java.applet.Applet class 4 life cycle methods and java.awt.Component class provides 1 life cycle methods for an applet.

java.applet.Applet class


For creating any applet java.applet.Applet class must be inherited. It provides 4 life cycle methods of applet.

1. public void init(): is used to initialized the Applet. It is invoked only once.
2. public void start(): is invoked after the init() method or browser is maximized. It is used to start the Applet.
3. public void stop(): is used to stop the Applet. It is invoked when Applet is stop or browser is minimized.
4. public void destroy(): is used to destroy the Applet. It is invoked only once.


java.awt.Component class


The Component class provides 1 life cycle method of applet.

1. public void paint(Graphics g): is used to paint the Applet. It provides Graphics class object that can be used for drawing oval, rectangle, arc etc.


Who is responsible to manage the life cycle of an applet?


Java Plug-in software.

How to run an Applet?


There are two ways to run an applet

1. By html file.
2. By appletViewer tool (for testing purpose).


Simple example of Applet by html file:


To execute the applet by html file, create an applet and compile it. After that create an html file and place the applet code in html file. Now click the html file.

//First.java  
import java.applet.Applet;  
import java.awt.Graphics;  
public class First extends Applet{  
  
public void paint(Graphics g){  
g.drawString("welcome",150,150);  
}  
  
}  

Note: class must be public because its object is created by Java Plugin software that resides on the browser.

myapplet.html

<html>  
<body>  
<applet code="First.class" width="300" height="300">  
</applet>  
</body>  
</html>  

Simple example of Applet by appletviewer tool:


To execute the applet by appletviewer tool, create an applet that contains applet tag in comment and compile it. After that run it by: appletviewer First.java. Now Html file is not required but it is for testing purpose only.

//First.java  
import java.applet.Applet;  
import java.awt.Graphics;  
public class First extends Applet{  
  
public void paint(Graphics g){  
g.drawString("welcome to applet",150,150);  
}  
  
}  
/* 
<applet code="First.class" width="300" height="300"> 
</applet> 
*/  

To execute the applet by appletviewer tool, write in command prompt:

c:\>javac First.java
c:\>appletviewer First.java

Sunday, January 26, 2020

What are the major features of Java programming?

Following are the notable features of Java:

Oracle Java Programming, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep

Object Oriented


In Java, everything is an Object. Java can be easily extended since it is based on the Object model.

Platform Independent


Unlike many other programming languages including C and C++, when Java is compiled, it is not compiled into platform specific machine, rather into platform-independent byte code. This byte code is distributed over the web and interpreted by the Virtual Machine (JVM) on whichever platform it is being run on.

Simple


Java is designed to be easy to learn. If you understand the basic concept of OOP Java, it would be easy to master.

Secure


With Java's secure feature it enables to develop virus-free, tamper-free systems. Authentication techniques are based on public-key encryption.

Architecture-neutral


Java compiler generates an architecture-neutral object file format, which makes the compiled code executable on many processors, with the presence of Java runtime system.

Portable


Being architecture-neutral and having no implementation dependent aspects of the specification makes Java portable. The compiler in Java is written in ANSI C with a clean portability boundary, which is a POSIX subset.

Robust


Java makes an effort to eliminate error-prone situations by emphasizing mainly on compile time error checking and runtime checking.

Multithreaded


With Java's multithreaded feature it is possible to write programs that can perform many tasks simultaneously. This design feature allows the developers to construct interactive applications that can run smoothly.

Interpreted


Java byte code is translated on the fly to native machine instructions and is not stored anywhere. The development process is more rapid and analytical since the linking is an incremental and light-weight process.

High Performance


With the use of Just-In-Time compilers, Java enables high performance.

Distributed


Java is designed for the distributed environment of the internet.

Dynamic


Java is considered to be more dynamic than C or C++ since it is designed to adapt to an evolving environment. Java programs can carry an extensive amount of run-time information that can be used to verify and resolve accesses to objects at run-time.

Thursday, January 23, 2020

Difference between Sun (Oracle) JVM and IBM JVM

Sun (Oracle) JVM, IBM JVM, Oracle Java Study Materials, Oracle Java Learning, Oracle Java Online Exam

There are different JVM implementation available apart from popular Sun's (now Oracle) hotspot JVM like IBM's JVM. Now the question comes, what makes two JVM different to each other? Quite a lot of thing can be different even if two JVMs are implemented by following Java virtual machine specification. IBM has its own JVM implementation which is different than Oracle's JVM in many things like JIT(Just in Time) Compiler, structure of Java heap, garbage collectors and support for monitoring and management. Though I have mostly used Sun’s hotspot JVM recently got a chance to run some Java program on IBM JVM on AIX platform and In this article I will shared some differences between Oracle and IBM JVM which is worth remembering. IBM's JVM is particularly useful on a platform which is not supported by Oracle like AIX systems.

IBM vs Oracle JVM


1) The first difference between Oracle and IBM JVM is that IBM uses different JIT and Garbage collectors than Oracle's JVM.

2) Another difference between IBM JVM and Oracle JVM is that IBM's JVM has different heap structure than Oracle's JVM. By default, IBM JVM does not use Generational Garbage Collector which can be enabled by JVM option (-Xgcpolicy:gencon)IBM JVM doesn't have PermGen space for storing class related metadata so free from PermGen OutOfMemoryError.

Difference between Sun (Oracle) JVM and IBM JVM
3) IBM JVM has a different kind of compiler known as Ahead Of time Compiler (AOT compiler) which work to reduce some overhead from JITing code whenever JVM starts. AOT compiler memory maps pre-compiled class file so that they don't need to go JIT compilation when IBM's JVM runs.

4) IBM JVM also supports class sharing which can be used to store classes which are shared across different JVM instances. This feature may available to Oracle JVM as well.

5) Earlier there was another different related to CompressOOPS but from Java6 update releases Oracle's JVM also support CompressedOOPS which is quite a handy JVM option to get better performance in 64 bit JVM.

6) IBM also provide some tools to monitor and analyze thread dumps which can be used to find deadlocks, resource contention, and bottleneck.

That's all on the difference between IBM and Oracle JVM. You won't notice much difference until you go real deep to get better performance and scalability stuff, for most of Java programs it just runs fine because both JVM support standard Java libraries.

Wednesday, January 22, 2020

Transaction Management in JDBC

Transaction represents a single unit of work.

Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java Study Materials, Oracle JDBC

The ACID properties describes the transaction management well. ACID stands for Atomicity, Consistency, isolation and durability.

Atomicity means either all successful or none.

Consistency ensures bringing the database from one consistent state to another consistent state.

Isolation ensures that transaction is isolated from other transaction.

Durability means once a transaction has been committed, it will remain so, even in the event of errors, power loss etc.

Advantage of Transaction Mangaement

fast performance It makes the performance fast because database is hit at the time of commit.

Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java Study Materials, Oracle JDBC

In JDBC, Connection interface provides methods to manage transaction.

Method Description 
void setAutoCommit(boolean status)   It is true bydefault means each transaction is committed bydefault.
void commit()   commits the transaction. 
void rollback()   cancels the transaction. 

Simple example of transaction management in jdbc using Statement


Let's see the simple example of transaction management using Statement.

import java.sql.*;  
class FetchRecords{  
public static void main(String args[])throws Exception{  
Class.forName("oracle.jdbc.driver.OracleDriver");  
Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","system","oracle");  
con.setAutoCommit(false);  
  
Statement stmt=con.createStatement();  
stmt.executeUpdate("insert into user420 values(190,'abhi',40000)");  
stmt.executeUpdate("insert into user420 values(191,'umesh',50000)");  
  
con.commit();  
con.close();  
}}  

If you see the table emp400, you will see that 2 records has been added.

Example of transaction management in jdbc using PreparedStatement


Let's see the simple example of transaction management using PreparedStatement.

import java.sql.*;  
import java.io.*;  
class TM{  
public static void main(String args[]){  
try{  
  
Class.forName("oracle.jdbc.driver.OracleDriver");  
Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","system","oracle");  
con.setAutoCommit(false);  
  
PreparedStatement ps=con.prepareStatement("insert into user420 values(?,?,?)");  
  
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
while(true){  
  
System.out.println("enter id");  
String s1=br.readLine();  
int id=Integer.parseInt(s1);  
  
System.out.println("enter name");  
String name=br.readLine();  
  
System.out.println("enter salary");  
String s3=br.readLine();  
int salary=Integer.parseInt(s3);  
  
ps.setInt(1,id);  
ps.setString(2,name);  
ps.setInt(3,salary);  
ps.executeUpdate();  
  
System.out.println("commit/rollback");  
String answer=br.readLine();  
if(answer.equals("commit")){  
con.commit();  
}  
if(answer.equals("rollback")){  
con.rollback();  
}  
  
  
System.out.println("Want to add more records y/n");  
String ans=br.readLine();  
if(ans.equals("n")){  
break;  
}  
  
}  
con.commit();  
System.out.println("record successfully saved");  
  
con.close();//before closing connection commit() is called  
}catch(Exception e){System.out.println(e);}  
  
}}  

It will ask to add more records until you press n. If you press n, transaction is committed.

Tuesday, January 21, 2020

Java Database Connectivity with Oracle

Java Database Connectivity with Oracle, Oracle Java Study Materials, Oracle Java Online Exam, Oracle Java Prep

To connect java application with the oracle database, we need to follow 5 following steps. In this example, we are using Oracle 10g as the database. So we need to know following information for the oracle database:

1. Driver class: The driver class for the oracle database is oracle.jdbc.driver.OracleDriver.

2. Connection URL: The connection URL for the oracle10G database is jdbc:oracle:thin:@localhost:1521:xe where jdbc is the API, oracle is the database, thin is the driver, localhost is the server name on which oracle is running, we may also use IP address, 1521 is the port number and XE is the Oracle service name. You may get all these information from the tnsnames.ora file.

3. Username: The default username for the oracle database is system.

4. Password: It is the password given by the user at the time of installing the oracle database.

Create a Table

Before establishing connection, let's first create a table in oracle database. Following is the SQL query to create a table.

create table emp(id number(10),name varchar2(40),age number(3)); 

Example to Connect Java Application with Oracle database


In this example, we are connecting to an Oracle database and getting data from emp table. Here, system and oracle are the username and password of the Oracle database.

import java.sql.*; 
class OracleCon{ 
public static void main(String args[]){ 
try{ 
//step1 load the driver class 
Class.forName("oracle.jdbc.driver.OracleDriver"); 
 
//step2 create  the connection object 
Connection con=DriverManager.getConnection( 
"jdbc:oracle:thin:@localhost:1521:xe","system","oracle"); 
 
//step3 create the statement object 
Statement stmt=con.createStatement(); 
 
//step4 execute query 
ResultSet rs=stmt.executeQuery("select * from emp"); 
while(rs.next()) 
System.out.println(rs.getInt(1)+"  "+rs.getString(2)+"  "+rs.getString(3)); 
 
//step5 close the connection object 
con.close(); 
 
}catch(Exception e){ System.out.println(e);} 
 



download this example

The above example will fetch all the records of emp table.

To connect java application with the Oracle database ojdbc14.jar file is required to be loaded.

download the jar file ojdbc14.jar

Two ways to load the jar file:

1. paste the ojdbc14.jar file in jre/lib/ext folder
2. set classpath

1) paste the ojdbc14.jar file in JRE/lib/ext folder:

Firstly, search the ojdbc14.jar file then go to JRE/lib/ext folder and paste the jar file here.

2) set classpath:

There are two ways to set the classpath:

◉ temporary
◉ permanent

Java Database Connectivity with Oracle, Oracle Java Study Materials, Oracle Java Online Exam, Oracle Java Prep
How to set the temporary classpath:

Firstly, search the ojdbc14.jar file then open command prompt and write:

C:>set classpath=c:\folder\ojdbc14.jar;.; 

How to set the permanent classpath:

Go to environment variable then click on new tab. In variable name write classpath and in variable value paste the path to ojdbc14.jar by appending ojdbc14.jar;.; as C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar;.;

Source: javatpoint.com

Monday, January 20, 2020

Difference between JDK, JRE, and JVM

We must understand the differences between JDK, JRE, and JVM before proceeding further to Java. See the brief overview of JVM here.

If you want to get the detailed knowledge of Java Virtual Machine, move to the next page. Firstly, let's see the differences between the JDK, JRE, and JVM.

JVM


JVM (Java Virtual Machine) is an abstract machine. It is called a virtual machine because it doesn't physically exist. It is a specification that provides a runtime environment in which Java bytecode can be executed. It can also run those programs which are written in other languages and compiled to Java bytecode.

JVMs are available for many hardware and software platforms. JVM, JRE, and JDK are platform dependent because the configuration of each OS is different from each other. However, Java is platform independent. There are three notions of the JVM: specification, implementation, and instance.

The JVM performs the following main tasks:

◉ Loads code
◉ Verifies code
◉ Executes code
◉ Provides runtime environment

JRE


JRE is an acronym for Java Runtime Environment. It is also written as Java RTE. The Java Runtime Environment is a set of software tools which are used for developing Java applications. It is used to provide the runtime environment. It is the implementation of JVM. It physically exists. It contains a set of libraries + other files that JVM uses at runtime.

The implementation of JVM is also actively released by other companies besides Sun Micro Systems.

JDK, JRE, JVM, Oracle Java Study Material, Oracle Java Guides, Oracle Java Tutorial and Material, Oracle Java Prep

JDK


JDK is an acronym for Java Development Kit. The Java Development Kit (JDK) is a software development environment which is used to develop Java applications and applets. It physically exists. It contains JRE + development tools.

JDK is an implementation of any one of the below given Java Platforms released by Oracle Corporation:

◉ Standard Edition Java Platform

◉ Enterprise Edition Java Platform

◉ Micro Edition Java Platform

The JDK contains a private Java Virtual Machine (JVM) and a few other resources such as an interpreter/loader (java), a compiler (javac), an archiver (jar), a documentation generator (Javadoc), etc. to complete the development of a Java Application.

JDK, JRE, JVM, Oracle Java Study Material, Oracle Java Guides, Oracle Java Tutorial and Material, Oracle Java Prep

Saturday, January 18, 2020

Programming the GPU in Java

Programming a graphics processing unit (GPU) seems like a distant world from Java programming. This is understandable, because most of the use cases for Java are not applicable to GPUs. Nonetheless, GPUs offer teraflops of performance, so let’s explore their possibilities.

To make the topic approachable, I’ll spend some time explaining GPU architecture along with a little history, which will make it easier to dive into programming the hardware. Once I’ve shown how the GPU differs from CPU computing, I’ll show how to use GPUs in the Java world. Finally, I will describe the leading frameworks and libraries available for writing Java code and running it on GPUs, and I’ll provide some code samples.

A Little Background


The GPU was first popularized by Nvidia in 1999. It is a special processor designed to process graphical data before it is transferred to the display. In most cases, it enables some of the computation to be offloaded from the CPU, thus freeing CPU resources while speeding up those offloaded computations. The result is that more input data can be processed and presented at much higher output resolutions, making the visual representation more attractive and the frame rate more fluid.

The nature of 2D/3D processing is mostly matrix manipulation, so it can be handled with a massively parallel approach. What would be an effective approach for image processing? To answer this, let’s compare the architecture of standard CPUs (shown in Figure 1) and GPUs.

Oracle Java Tutorials and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Certifications, Oracle Java Prep

Figure 1. Block architecture of a CPU

In the CPU, the actual processing elements—the fetchers, the arithmetic logic unit (ALU), and the execution contexts—are just a small part of the whole system. To speed up the irregular calculations arriving in unpredictable order, there are a large, fast, and expensive cache; different kinds of prefetchers; and branch predictors.

You don’t need all of this on a GPU, because the data is received in a predictable manner and the GPU performs a very limited set of operations on the data. Thus, it is possible to make a very small and inexpensive processor with a block architecture similar to that in Figure 2.

Oracle Java Tutorials and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Certifications, Oracle Java Prep

Figure 2. Block architecture for a simple GPU core

Because these kinds of processors are cheap and they process data in parallel chunks, it’s easy to put many of them to work in parallel. This design is referred to as multiple instruction, multiple data or MIMD (pronounced “mim-dee”).

A second approach focuses on the fact that often a single instruction is applied to multiple data items. This is known as single instruction, multiple data or SIMD (pronounced “sim-dee”). In this design, a single GPU contains multiple ALUs and execution contexts, with a small area dedicated to shared context data, as shown in Figure 3.

Oracle Java Tutorials and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Certifications, Oracle Java Prep

Figure 3. Comparing a MIMD-style GPU block architecture (left) with a SIMD design (right)

Combining SIMD and MIMD processing provides the maximal processing throughput, which I’ll discuss shortly. In such a design, you have multiple SIMD processors running in parallel, as shown in Figure 4.

Oracle Java Tutorials and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Certifications, Oracle Java Prep

Figure 4. Running multiple SIMD processors in parallel; here, 16 cores with 128 total ALUs

Because you have a bunch of small, simple processors, you can program them to gain special effects in the output.

Running Programs on the GPU


Most of the early visual effects in games were actually hardcoded small programs running on a GPU and applied to the data stream from the CPU.

It was obvious, even then, that hardcoded algorithms were insufficient, especially in game design, where visual representation is actually one of the main selling points. In response, the big vendors opened access to GPUs, and then third-party developers could code for them.

The typical approach was to write small programs, called shaders, in a special language (usually a subset of C) and compile them with a special compiler for the corresponding architecture. The term shaders was chosen because shaders were often used to control lighting and shading effects, but there’s no reason they can’t handle other special effects.

Each GPU vendor had its own specific programming language and infrastructure for creating shaders for its hardware. From these efforts, several platforms have been created. The major ones include

DirectCompute: A proprietary shader language/API from Microsoft that is part of Direct3D, starting with DirectX 10

AMD FireStream: An ATI/Radeon proprietary technology, which was discontinued by AMD

OpenACC: A multivendor-consortium parallel computing solution

C++ AMP: A Microsoft proprietary library for data parallelism in C++

CUDA: Nvidia’s proprietary platform, which uses a subset of the C language

OpenCL: A common standard originally designed by Apple but now managed by the consortium Khronos Group

Most of the time, working with GPUs is low-level programming. To make it a little bit more understandable for developers to code, several abstractions are provided. The most famous are DirectX, from Microsoft, and OpenGL, from the Khronos Group. These APIs are for writing high-level code, which then can be offloaded to the GPU mostly seamlessly by the developer.

As far as I know, there is no Java infrastructure that supports DirectX, but there is a nice binding for OpenGL. JSR 231 was started in 2002 to address GPU programming, but it was abandoned in 2008 and supported only OpenGL 2.0. Support of OpenGL has been continued in an independent project called JOCL, (which also supports OpenCL), and it’s publicly available. By the way, the famous Minecraft game was written with JOCL underneath.

Advent of the GPGPU


Still, Java and GPUs are not a seamless fit, although they should be. Java is heavily used in enterprises, data science, and the financial sector, where many computations and a lot of processing power are needed. This is how the idea of the general-purpose GPU (GPGPU) came about.

The idea to use the GPU this way started when the vendors of video adapters started to open the frame buffer programmatically, enabling developers to read the contents. Some hackers recognized that they could then use the full power of the GPU for general-purpose computations. The recipe was straightforward:

1. Encode the data as a bitmap array.
2. Write a shader to process it.
3. Submit them both to the video card.
4. Retrieve the result from the frame buffer.
5. Decode the data from the bitmap array.

This is a very simplified explanation. I’m not sure this process was ever heavily used in production, but it did work.

Then several researchers from Stanford University began looking for a way to make using a GPGPU easier. In 2005 they released BrookGPU, which was a small ecosystem that included a language, a compiler, and a runtime.

BrookGPU compiled programs written in the Brook stream programming language, which is a variant of ANSI C. It could target OpenGL v1.3+, DirectX v9+, or AMD’s Close to Metal for the computational back end, and it ran on both Microsoft Windows and Linux. For debugging, BrookGPU could also simulate a virtual graphics card on the CPU.

However, it did not take off, because of the hardware available at the time. In the GPGPU world, you need to copy the data to the device (in this context, device refers to the GPU and the board on which it is situated), wait for the GPU to process the data, and then copy the data back to the main runtime. This creates a lot of latency. And in the mid-2000s, when the project was under active development, this latency almost precluded extensive use of GPUs for general computing.

Nevertheless, many companies saw a future in this technology. Several video adapter vendors started providing GPGPUs with their proprietary technologies, and others formed alliances to provide more-general, versatile programming models to run a larger variety of hardware devices.

Now that I’ve shared this background, let’s examine the two most successful technologies for GPU computing—OpenCL and CUDA—and see how Java works with them.

OpenCL and Java


Like many other infrastructure packages, OpenCL provides a base implementation in C. It is technically accessible via Java Native Interface (JNI) or Java Native Access (JNA), but such access would be a bit too much work for most developers. Fortunately, this work has already been done by several libraries: JOCL, JogAmp, and JavaCL. Unfortunately, JavaCL is a dead project. But the JOCL project is alive and quite up to date. I will use it in the following examples.

But first I should explain what OpenCL is. As I mentioned earlier, OpenCL provides a very general model, suitable for programming all sorts of devices—not only GPUs and CPUs but even digital signal processors (DSPs) and field-programmable gate arrays (FPGAs) as well.

Let’s explore the easiest example: vector addition, probably the most representative and simple example. You have two integer arrays you’re adding and one resulting array. You take an element from the first array and an element from the second array, and then you put the sum of them in the result array, as shown in Figure 5.

Oracle Java Tutorials and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Certifications, Oracle Java Prep

Figure 5. Adding the contents of two arrays and storing the sums in a result array

As you can see, the operation is highly concurrent and thus very parallelizable. You can push each of the add operations to a separate GPU core. This means that if you have 2,048 cores, as on an Nvidia 1080 graphics card, you can perform 2,048 simultaneous add operations. That means there are potentially teraflops of computing power waiting for you. Here is the code for arrays with 10 million integers taken from the JOCL site:

public class ArrayGPU {
    /**
     * The source code of the OpenCL program 
     */
    private static String programSource =
        "__kernel void "+
        "sampleKernel(__global const float *a,"+
        "             __global const float *b,"+
        "             __global float *c)"+
        "{"+
        "    int gid = get_global_id(0);"+
        "    c[gid] = a[gid] + b[gid];"+
        "}";
    
    public static void main(String args[])
    {
        int n = 10_000_000;
        float srcArrayA[] = new float[n];
        float srcArrayB[] = new float[n];
        float dstArray[] = new float[n];
        for (int i=0; i<n; i++)
        {
            srcArrayA[i] = i;
            srcArrayB[i] = i;
        }
        Pointer srcA = Pointer.to(srcArrayA);
        Pointer srcB = Pointer.to(srcArrayB);
        Pointer dst = Pointer.to(dstArray);


        // The platform, device type and device number
        // that will be used
        final int platformIndex = 0;
        final long deviceType = CL.CL_DEVICE_TYPE_ALL;
        final int deviceIndex = 0;

        // Enable exceptions and subsequently omit error checks in this sample
        CL.setExceptionsEnabled(true);

        // Obtain the number of platforms
        int numPlatformsArray[] = new int[1];
        CL.clGetPlatformIDs(0, null, numPlatformsArray);
        int numPlatforms = numPlatformsArray[0];

        // Obtain a platform ID
        cl_platform_id platforms[] = new cl_platform_id[numPlatforms];
        CL.clGetPlatformIDs(platforms.length, platforms, null);
        cl_platform_id platform = platforms[platformIndex];

        // Initialize the context properties
        cl_context_properties contextProperties = new cl_context_properties();
        contextProperties.addProperty(CL.CL_CONTEXT_PLATFORM, platform);
        
        // Obtain the number of devices for the platform
        int numDevicesArray[] = new int[1];
        CL.clGetDeviceIDs(platform, deviceType, 0, null, numDevicesArray);
        int numDevices = numDevicesArray[0];
        
        // Obtain a device ID 
        cl_device_id devices[] = new cl_device_id[numDevices];
        CL.clGetDeviceIDs(platform, deviceType, numDevices, devices, null);
        cl_device_id device = devices[deviceIndex];

        // Create a context for the selected device
        cl_context context = CL.clCreateContext(
            contextProperties, 1, new cl_device_id[]{device}, 
            null, null, null);
        
        // Create a command-queue for the selected device
        cl_command_queue commandQueue = 
            CL.clCreateCommandQueue(context, device, 0, null);

        // Allocate the memory objects for the input and output data
        cl_mem memObjects[] = new cl_mem[3];
        memObjects[0] = CL.clCreateBuffer(context,
            CL.CL_MEM_READ_ONLY | CL.CL_MEM_COPY_HOST_PTR,
            Sizeof.cl_float * n, srcA, null);
        memObjects[1] = CL.clCreateBuffer(context,
            CL.CL_MEM_READ_ONLY | CL.CL_MEM_COPY_HOST_PTR,
            Sizeof.cl_float * n, srcB, null);
        memObjects[2] = CL.clCreateBuffer(context,
            CL.CL_MEM_READ_WRITE,
            Sizeof.cl_float * n, null, null);
        
        // Create the program from the source code
        cl_program program = CL.clCreateProgramWithSource(context,
            1, new String[]{ programSource }, null, null);
        
        // Build the program
        CL.clBuildProgram(program, 0, null, null, null, null);
        
        // Create the kernel
        cl_kernel kernel = CL.clCreateKernel(program, "sampleKernel", null);
        
        // Set the arguments for the kernel
        CL.clSetKernelArg(kernel, 0,
            Sizeof.cl_mem, Pointer.to(memObjects[0]));
        CL.clSetKernelArg(kernel, 1,
            Sizeof.cl_mem, Pointer.to(memObjects[1]));
        CL.clSetKernelArg(kernel, 2,
            Sizeof.cl_mem, Pointer.to(memObjects[2]));
        
        // Set the work-item dimensions
        long global_work_size[] = new long[]{n};
        long local_work_size[] = new long[]{1};
        
        // Execute the kernel
        CL.clEnqueueNDRangeKernel(commandQueue, kernel, 1, null,
            global_work_size, local_work_size, 0, null, null);
        
        // Read the output data
        CL.clEnqueueReadBuffer(commandQueue, memObjects[2], CL.CL_TRUE, 0,
            n * Sizeof.cl_float, dst, 0, null, null);
        
        // Release kernel, program, and memory objects
        CL.clReleaseMemObject(memObjects[0]);
        CL.clReleaseMemObject(memObjects[1]);
        CL.clReleaseMemObject(memObjects[2]);
        CL.clReleaseKernel(kernel);
        CL.clReleaseProgram(program);
        CL.clReleaseCommandQueue(commandQueue);
        CL.clReleaseContext(context);

    }

    private static String getString(cl_device_id device, int paramName) {
        // Obtain the length of the string that will be queried
        long size[] = new long[1];
        CL.clGetDeviceInfo(device, paramName, 0, null, size);

        // Create a buffer of the appropriate size and fill it with the info
        byte buffer[] = new byte[(int)size[0]];
        CL.clGetDeviceInfo(device, paramName, buffer.length, Pointer.to(buffer), null);

        // Create a string from the buffer (excluding the trailing \0 byte)
        return new String(buffer, 0, buffer.length-1);
    }
}

This code doesn’t look like Java, but it actually is. I’ll explain the code next; don’t spend a lot of time on it now, because I will shortly discuss less complicated solutions.

The code is well documented, but let’s do a small walk-through. As you can see, the code is very C-like. This is quite normal, because JOCL is just the binding to OpenCL. At the start, there is some code inside a string, and this code is actually the most important part: It gets compiled by OpenCL and then sent to the video card and executed there. This code is called a kernel. Do not confuse this term with an OS kernel; this is the device code. This kernel code is written in a subset of C.

After the kernel comes the Java binding code to set up and orchestrate the device, to chunk the data, and to create proper memory buffers on the device where the data is going to be stored as well as the memory buffers for the resulting data.

To summarize: There is “host code,” which is usually a language binding (in this case, Java), and the “device code.” You always distinguish what runs on the host and what should run on the device, because the host controls the device.

The preceding code should be viewed as the GPU equivalent of “Hello World!” As you see, the amount of ceremony is vast.

Let’s not forget the SIMD capabilities. If your hardware supports SIMD extensions, you can make arithmetic code run much faster. For example, let’s look at the matrix multiplication kernel code. This is the code in the raw string of your Java application.

__kernel void MatrixMul_kernel_basic(int dim,
                  __global float *A,
                  __global float *B,
                  __global float *C){

    int iCol = get_global_id(0);
    int iRow = get_global_id(1);
    float result = 0.0;
    for(int i=0; i< dim; ++i)
    {
          result +=
          A[iRow*dim + i]*B[i*dim + iCol];
    }
    C[iRow*dim + iCol] = result;
}

Technically, this code will work on a chunk of data that was set up for you by the OpenCL framework, with the instructions you supply in the preparation ceremony.

If your video card supports SIMD instructions and is able to process vectors of four floats, a small optimization may turn the previous code into the following code:

#define VECTOR_SIZE 4    
__kernel void MatrixMul_kernel_basic_vector4(
    size_t dim, // dimension is in single floats
    const float4 *A,
    const float4 *B,
    float4 *C)
{
    size_t globalIdx = get_global_id(0);
    size_t globalIdy = get_global_id(1);
    float4 resultVec = (float4){ 0, 0, 0, 0 };
    size_t dimVec = dim / 4;
    for(size_t i = 0; i < dimVec; ++i) {
        float4 Avector = A[dimVec * globalIdy + i];
        float4 Bvector[4];
        Bvector[0] = B[dimVec * (i * 4 + 0) + globalIdx];
        Bvector[1] = B[dimVec * (i * 4 + 1) + globalIdx];
        Bvector[2] = B[dimVec * (i * 4 + 2) + globalIdx];
        Bvector[3] = B[dimVec * (i * 4 + 3) + globalIdx];
        resultVec += Avector[0] * Bvector[0];
        resultVec += Avector[1] * Bvector[1];
        resultVec += Avector[2] * Bvector[2];
        resultVec += Avector[3] * Bvector[3];
    }

    C[dimVec * globalIdy + globalIdx] = resultVec;
}

With this code, you can double the performance.

Cool. You have unlocked the GPU for the Java world! But as a Java developer, do you really want to do all of this binding, write C code, and work with such low-level details? I certainly don’t. But now that you have some knowledge of how the GPU architecture is used, let’s look at other solutions beyond the JOCL code I’ve just presented.

CUDA and Java


CUDA is Nvidia’s solution to these coding issues. CUDA provides many more ready-to-use libraries for standard GPU operations, such as matrices, histograms, and even deep neural networks. The emerging library list already contains many useful bindings. These are from the JCuda project:

◉ JCublas: all about matrices

◉ JCufft: fast Fourier transforms

◉ JCurand: all about random numbers

◉ JCusparse: sparse matrices

◉ JCusolver: factorization

◉ JNvgraph: all about graphs

◉ JCudpp: CUDA Data Parallel Primitives Library and some sorting algorithms

◉ JNpp: image processing on a GPU

◉ JCudnn: a deep neural network library

I’ll describe using JCurand, which generates random numbers. You can directly use it from Java code with no other specific kernel languages. For example:

...
int n = 100;
curandGenerator generator = new curandGenerator();
float hostData[] = new float[n];
Pointer deviceData = new Pointer();
cudaMalloc(deviceData, n * Sizeof.FLOAT);
curandCreateGenerator(generator, CURAND_RNG_PSEUDO_DEFAULT); 
curandSetPseudoRandomGeneratorSeed(generator, 1234);
curandGenerateUniform(generator, deviceData, n);
cudaMemcpy(Pointer.to(hostData), deviceData, 
        n * Sizeof.FLOAT, cudaMemcpyDeviceToHost);
System.out.println(Arrays.toString(hostData));
curandDestroyGenerator(generator);
cudaFree(deviceData);
...

Here the GPU is used to create more random numbers of high quality, based on some very strong mathematics.

In JCuda you can also write generic CUDA code and call it from Java by just adding some JAR files to your classpath.

Staying Above Low-Level Code


This all looks great, but there is too much ceremony, too much setup, and too many different languages to get this running. Is there a way to use a GPU at least partially?

What if you don’t want to think about all of this OpenCL, CUDA, and other internal stuff? What if you just want to code in Java and not think about the internals? The Aparapi project can help. Aparapi stands for “a parallel API.” I think of it as a kind of Hibernate for GPU programming that uses OpenCL under the hood. Let’s look at an example of vector addition.

public static void main(String[] _args) {
    final int size = 512;
    final float[] a = new float[size];
    final float[] b = new float[size];

    /* fill the arrays with random values */
    for (int i = 0; i < size; i++){
        a[i] = (float) (Math.random() * 100);
        b[i] = (float) (Math.random() * 100);
    }
    final float[] sum = new float[size];

    Kernel kernel = new Kernel(){
        @Override public void run() {
I           int gid = getGlobalId();
            sum[gid] = a[gid] + b[gid];
        }
    };

    kernel.execute(Range.create(size));
    for(int i = 0; i < size; i++) {
        System.out.printf("%6.2f + %6.2f = %8.2f\n", a[i], b[i], sum[i])
    }
    kernel.dispose();
}

This is pure Java code (taken from the Aparapi documentation), although here and there, you can spot some GPU domain-specific terms such as Kernel and getGlobalId. You still need to understand how the GPU is programmed, but you can approach GPGPU in a more Java-friendly way. Moreover, Aparapi provides an easy way to bind OpenGL contexts to the OpenCL layer underneath—thus enabling the data to stay entirely on the video card—and thereby avoid memory latency issues.

If many independent computations need to be done, consider Aparapi. This rich set of examples gives some use cases that are perfect for massive parallel computations.

In addition, there are several projects such as TornadoVM that automatically offload suitable calculations from the CPU to the GPU, thus enabling massive optimizations out of the box.

Source: oracle.com