Wednesday, August 26, 2020

Generics in Java

 

Generics in Java

The Java Generics programming is introduced in J2SE 5 to deal with type-safe objects. It makes the code stable by detecting the bugs at compile time.

Before generics, we can store any type of objects in the collection, i.e., non-generic. Now generics force the java programmer to store a specific type of objects.

Advantage of Java Generics

There are mainly 3 advantages of generics. They are as follows:

1) Type-safety: We can hold only a single type of objects in generics. It doesn?t allow to store other objects.

Without Generics, we can store any type of objects.

  1. List list = new ArrayList();    
  2. list.add(10);  
  3. list.add("10");  
  4. With Generics, it is required to specify the type of object we need to store.  
  5. List<Integer> list = new ArrayList<Integer>();    
  6. list.add(10);  
  7. list.add("10");// compile-time error  

2) Type casting is not required: There is no need to typecast the object.

Before Generics, we need to type cast.

  1. List list = new ArrayList();    
  2. list.add("hello");    
  3. String s = (String) list.get(0);//typecasting    
  4. After Generics, we don't need to typecast the object.  
  5. List<String> list = new ArrayList<String>();    
  6. list.add("hello");    
  7. String s = list.get(0);    

3) Compile-Time Checking: It is checked at compile time so problem will not occur at runtime. The good programming strategy says it is far better to handle the problem at compile time than runtime.

  1. List<String> list = new ArrayList<String>();    
  2. list.add("hello");    
  3. list.add(32);//Compile Time Error    

Syntax to use generic collection

  1. ClassOrInterface<Type>    

Example to use Generics in java

  1. ArrayList<String>    

Full Example of Generics in Java

Here, we are using the ArrayList class, but you can use any collection class such as ArrayList, LinkedList, HashSet, TreeSet, HashMap, Comparator etc.

  1. import java.util.*;  
  2. class TestGenerics1{  
  3. public static void main(String args[]){  
  4. ArrayList<String> list=new ArrayList<String>();  
  5. list.add("rahul");  
  6. list.add("jai");  
  7. //list.add(32);//compile time error  
  8.   
  9. String s=list.get(1);//type casting is not required  
  10. System.out.println("element is: "+s);  
  11.   
  12. Iterator<String> itr=list.iterator();  
  13. while(itr.hasNext()){  
  14. System.out.println(itr.next());  
  15. }  
  16. }  
  17. }  

  1. import java.util.*;  
  2. class TestGenerics1{  
  3. public static void main(String args[]){  
  4. ArrayList<String> list=new ArrayList<String>();  
  5. list.add("rahul");  
  6. list.add("jai");  
  7. //list.add(32);//compile time error  
  8.   
  9. String s=list.get(1);//type casting is not required  
  10. System.out.println("element is: "+s);  
  11.   
  12. Iterator<String> itr=list.iterator();  
  13. while(itr.hasNext()){  
  14. System.out.println(itr.next());  
  15. }  
  16. }  
  17. }  

Tuesday, August 25, 2020

Keywords:

Volatile:

Volatile Keyword in Java

Volatile keyword is used to modify the value of a variable by different threads. It is also used to make classes thread safe. It means that multiple threads can use a method and instance of the classes at the same time without any problem. The volatile keyword can be used either with primitive type or objects.

The volatile keyword does not cache the value of the variable and always read the variable from the main memory. The volatile keyword cannot be used with classes or methods. However, it is used with variables. It also guarantees visibility and ordering. It prevents the compiler from the reordering of code.

The contents of the particular device register could change at any time, so you need the volatile keyword to ensure that such accesses are not optimized away by the compiler.



Atomic Variable: 

1. Introduction

Simply put, a shared mutable state very easily leads to problems when concurrency is involved. If access to shared mutable objects is not managed properly, applications can quickly become prone to some hard-to-detect concurrency errors.

In this article, we'll revisit the use of locks to handle concurrent access, explore some of the disadvantages associated with locks, and finally, introduce atomic variables as an alternative.

2. Lock

Let's have a look at the class:

public class Counter {
int counter;
public void increment() {
counter++;
}
}

In the case of a single-threaded environment, this works perfectly; however, as soon as we allow more than one thread to write, we start getting inconsistent results.

This is because of the simple increment operation (counter++), which may look like an atomic operation, but in fact is a combination of three operations: obtaining the value, incrementing, and writing the updated value back.

If two threads try to get and update the value at the same time, it may result in lost updates.

One of the ways to manage access to an object is to use locks. This can be achieved by using the synchronized keyword in the increment method signature. The synchronized keyword ensures that only one thread can enter the method at one time (to learn more about Locking and Synchronization refer to – Guide to Synchronized Keyword in Java):

public class SafeCounterWithLock {
private volatile int counter;
public synchronized void increment() {
counter++;
}
}

Additionally, we need to add the volatile keyword to ensure proper reference visibility among threads.

Using locks solves the problem. However, the performance takes a hit.

When multiple threads attempt to acquire a lock, one of them wins, while the rest of the threads are either blocked or suspended.

The process of suspending and then resuming a thread is very expensive and affects the overall efficiency of the system.

In a small program, such as the counter, the time spent in context switching may become much more than actual code execution, thus greatly reducing overall efficiency.

3. Atomic Operations

There is a branch of research focused on creating non-blocking algorithms for concurrent environments. These algorithms exploit low-level atomic machine instructions such as compare-and-swap (CAS), to ensure data integrity.

A typical CAS operation works on three operands:

  1. The memory location on which to operate (M)
  2. The existing expected value (A) of the variable
  3. The new value (B) which needs to be set

The CAS operation updates atomically the value in M to B, but only if the existing value in M matches A, otherwise no action is taken.

In both cases, the existing value in M is returned. This combines three steps – getting the value, comparing the value, and updating the value – into a single machine level operation.

When multiple threads attempt to update the same value through CAS, one of them wins and updates the value. However, unlike in the case of locks, no other thread gets suspended; instead, they're simply informed that they did not manage to update the value. The threads can then proceed to do further work and context switches are completely avoided.

One other consequence is that the core program logic becomes more complex. This is because we have to handle the scenario when the CAS operation didn't succeed. We can retry it again and again till it succeeds, or we can do nothing and move on depending on the use case.

4. Atomic Variables in Java

The most commonly used atomic variable classes in Java are AtomicIntegerAtomicLongAtomicBoolean, and AtomicReference. These classes represent an intlongboolean, and object reference respectively which can be atomically updated. The main methods exposed by these classes are:

  • get() – gets the value from the memory, so that changes made by other threads are visible; equivalent to reading a volatile variable
  • set() – writes the value to memory, so that the change is visible to other threads; equivalent to writing a volatile variable
  • lazySet() – eventually writes the value to memory, maybe reordered with subsequent relevant memory operations. One use case is nullifying references, for the sake of garbage collection, which is never going to be accessed again. In this case, better performance is achieved by delaying the null volatile write
  • compareAndSet() – same as described in section 3, returns true when it succeeds, else false
  • weakCompareAndSet() – same as described in section 3, but weaker in the sense, that it does not create happens-before orderings. This means that it may not necessarily see updates made to other variables. As of Java 9, this method has been deprecated in all atomic implementations in favor of weakCompareAndSetPlain(). The memory effects of weakCompareAndSet() were plain but its names implied volatile memory effects. To avoid this confusion, they deprecated this method and added four methods with different memory effects such as weakCompareAndSetPlain() or weakCompareAndSetVolatile()

A thread-safe counter implemented with AtomicInteger is shown in the example below:

public class SafeCounterWithoutLock {
private final AtomicInteger counter = new AtomicInteger(0);
public int getValue() {
return counter.get();
}
public void increment() {
while(true) {
int existingValue = getValue();
int newValue = existingValue + 1;
if(counter.compareAndSet(existingValue, newValue)) {
return;
}
}
}
}

As you can see, we retry the compareAndSet operation and again on failure, since we want to guarantee that the call to the increment method always increases the value by 1.

5. ConclusionIn this quick tutorial, we described an alternate way of handling concurrency where disadvantages associated with locking can be avoided. We also looked at the main methods exposed by the atomic variable classes in Java.

Saturday, August 22, 2020

SpringBoot application.properties

For non-web project(standalone application)👇:

spring.datasource.name=test
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL55Dialect
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

For web app👇:

server.port=8081
spring.mvc.view.prefix=/jsp/
spring.mvc.view.suffix=.jsp
spring.h2.console.enabled=true
spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:manoj

  

Friday, August 21, 2020

 

Java Object Cache Concepts

Oracle9iAS offers the Java Object Cache to help e-businesses manage Web-site performance issues for dynamically generated content. The Java Object Cache improves the performance, scalability, and availability of Web sites running on Oracle9iAS.

By storing frequently accessed or expensive-to-create objects in memory or on disk, the Java Object Cache eliminates the need to repeatedly create and load information within a Java program. The Java Object Cache retrieves content faster and greatly reduces the load on application servers.


The Oracle9iAS cache architecture includes the following cache components:

  • Oracle 9iAS Web Cache. The Web Cache sits in front of the application servers (Web servers), caching their content and providing that content to Web browsers that request it. When browsers access the Web site, they send HTTP requests to the Web Cache. The Web Cache, in turn, acts as a virtual server to the application servers. If the requested content has changed, the Web cache retrieves the new content from the application servers.

    The Web Cache is an HTTP-level cache, maintained outside the application, providing very fast cache operations. It is a pure, content-based cache, capable of caching static data (such as HTML, GIF, or JPEG files) or dynamic data (such as servlet or JSP results). Given that it exists as a flat content-based cache outside the application, it cannot cache objects (such as Java objects or XML DOM--Document Object Model--objects) in a structured format. In addition, it offers relatively limited post-processing abilities on cached data.

  • Java Object Cache. The Java Object Cache provides caching for expensive or frequently used Java objects when the application servers use a Java program to supply their content. Cached Java objects may contain generated pages or may provide support objects within the program to assist in creating new content. The Java Object Cache automatically loads and updates objects as specified by the Java application.

  • Web Object Cache. The Web Object Cache is a web-application-level caching facility. It is an application-level cache, embedded and maintained within a Java Web application. The Web Object Cache is a hybrid cache, both Web-based and object-based. Using the Web Object Cache, applications can cache programmatically using API calls (for servlets) or custom tag libraries (for JSPs). The Web Object Cache is generally used as a complement to the Web cache. By default, the Web Object Cache uses the Java Object Cache as its repository.

    A custom tag library or API allows you to define page fragment boundaries and to capture, store, reuse, process, and manage the intermediate and partial execution results of JSP pages and servlets as cached objects. Each block can produce its own resulting cache object. The cached objects can be HTML or XML text fragments, XML DOM objects, or Java serializable objects. These objects can be cached conveniently in association with HTTP semantics. Alternatively, they can be reused outside HTTP, such as in outputting cached XML objects through Simple Mail Transfer Protocol (SMTP), Java Messaging Service (JMS), Advanced Queueing (AQ), or Simple Object Access Protocol (SOAP).

Cache Basic architechture

Text description of joc002.gif follows.

Resource

Guitar Chords

click on   Guitar Chords Family