Tuesday, September 29, 2015
How to handle Facebook Likes in thread safe way in Java(Multithreading + synchronized)
Multi threading is a concept where multiple operation can be done at the same time. For example, facebook likes. Single photo or Facebook pages can be liked by many Facebook users at that same time.
Today I am going to demonstrate how to handle it in thread safe way and how it will create problem if it is not thread safe.
1. create package with name: mthread
2. Create FacebookPage called FacebookLike as shown in below.
SourceCode: FacebookLike.java
3. Create Java file called SynchronizeFbLike as shown in screenshot:
Source: SynchronizeFbLike.java
We have created Object of FacebookLike page first. final keyword is added as we can only use either final or static object/variable inside Thread.
We have created four different anonymous threads. They have override run methods and inside run we have callled plusone() method of facebook page. Same thing is done in all the threads.
Initial value of likes in now 500(set from construtor).
This program is completely thread safe as we have used synchronized keyword in plusone() method.
So this is the output:
You can see result is working as expected. Now lets see how multi user program can create problem if it is not thread safe.
> remove synchronized keyword from FacebookPage>Plusone() method.
Output is like this:
Now you can see result is totally wrong. If four user hit plusone() result should be 501,502,503,504. Now one thread have replace value incremented by another thread. If we add synchronized keyword. Java add lock in plusone() method so that one thread can only call plusone() method at once.
Hope you have understand basic about how multi threading happen in real world example scenario.
If you enjoy this article feel free to like, share and comment.
Today I am going to demonstrate how to handle it in thread safe way and how it will create problem if it is not thread safe.
1. create package with name: mthread
2. Create FacebookPage called FacebookLike as shown in below.
SourceCode: FacebookLike.java
3. Create Java file called SynchronizeFbLike as shown in screenshot:
Source: SynchronizeFbLike.java
We have created Object of FacebookLike page first. final keyword is added as we can only use either final or static object/variable inside Thread.
We have created four different anonymous threads. They have override run methods and inside run we have callled plusone() method of facebook page. Same thing is done in all the threads.
Initial value of likes in now 500(set from construtor).
This program is completely thread safe as we have used synchronized keyword in plusone() method.
So this is the output:
You can see result is working as expected. Now lets see how multi user program can create problem if it is not thread safe.
> remove synchronized keyword from FacebookPage>Plusone() method.
Output is like this:
Now you can see result is totally wrong. If four user hit plusone() result should be 501,502,503,504. Now one thread have replace value incremented by another thread. If we add synchronized keyword. Java add lock in plusone() method so that one thread can only call plusone() method at once.
Hope you have understand basic about how multi threading happen in real world example scenario.
If you enjoy this article feel free to like, share and comment.
Tuesday, September 22, 2015
Console Calculator program using Java
This is sample Calculator program based on console input. You will be allowed to give input repeatedly until you type "exit".
Is does not check for precedence of character. It start to calculate from right to left recursively.
Here is the code:
import java.util.Scanner;
/**
* Sample Calculator without precedence check.
* @author ojhay
*
*/
public class CalculatorConsole {
public static void main( String[] args ) {
Scanner sc = new Scanner( System.in );
System.out.println( "Calculator:" );
while ( true ) {
System.out.print( "Type arithmetic Expression: " );
String expression = sc.nextLine( );
// Exit if user input: exit
if ( expression.equalsIgnoreCase( "exit" ) ) {
break;
}
double result = expre( expression );
System.out.println( expression + "= " + result );
}
sc.close( );
}
// Recursive method to evaluate arithmetic expression.
public static double expre( String expre ) {
if ( ! ( expre.contains( "+" ) || expre.contains( "-" ) || expre.contains( "*" ) || expre.contains( "/" ) ) ) {
return Integer.valueOf( expre );
}
double result = 0;
for ( int i = 0; i < expre.length( ); i++ ) {
char symbol = expre.charAt( i );
if ( !Character.isDigit( symbol ) ) { // Symbol
double operand1 = Integer.parseInt( expre.substring( 0, i ) );
switch ( symbol ) {
case '+':
result = operand1 + expre( expre.substring( i + 1 ) );
break;
case '-':
result = operand1 - expre( expre.substring( i + 1 ) );
break;
case '*':
result = operand1 * expre( expre.substring( i + 1 ) );
break;
case '/':
result = operand1 / expre( expre.substring( i + 1 ) );
break;
}
break;
}
}
return result;
}
}
Wednesday, August 19, 2015
Create and Download pdf from server using spring java and angular
Create Temporay file and then delete that file doesnot work.
So, We need to be carefull about FileInputStream and FileOutputStreams.
They must be closed before delete the file.
Here is complete example of how to create pdf and download pdf in two step:
---------------------------------------------------------------
@RequestMapping(value = "createPdf" , method=RequestMethod.POST)
public @ResponseBody JSONResult createPdf(){
JSONResult result = new JSONResult();
File f = null;
FileOutputStream out = null;
try{
f = File. createTempFile( "tmpPdf", ".pdf" , new File("D:\\temp" ));
out = new FileOutputStream(f);
IOUtils. copy( new FileInputStream( "E:\\fs.pdf" ), out );
out.flush( );
out.close( );
result.setData( f.getAbsolutePath( ) );
result.setSuccess( true );
} catch ( Exception e ) {
e.printStackTrace( );
result.setSuccess( false );
if(null != out){
try {
out.close( );
} catch ( IOException e1 ) {
e1.printStackTrace();
}
}
if(null != f){
f.delete( );
}
} finally {
if(null != out){
try {
out.close( );
} catch ( IOException e1 ) {
e1.printStackTrace();
}
}
}
return result;
}
@RequestMapping(value = "getPDF", method=RequestMethod.GET)
public void getPdf(@QueryParam ("filePath" ) String filePath, HttpServletResponse response) throws IOException{
File f = new File(filePath);
if(f.exists( )){
FileInputStream inputStream = new FileInputStream( filePath);
IOUtils. copy( inputStream, response.getOutputStream( ) );
response.setContentType( "application/pdf" );
response.setHeader( "Content-Disposition", "attachment; filename=somefile.pdf");
response.flushBuffer( );
inputStream.close( );
f.delete( );
} else {
throw new IOException();
}
}
=================================
$scope.downloadPdf = function(){
var win = window.open( '', '_blank');
try {
$http.post(getContext() + '/documents/createPdf').success(function (data, status, headers, config){
win.location.href = getContext() + '/documents/getPDF?filePath=' +encodeURIComponent(data.data);
win.focus();
});
} catch(e) {
win.close();
return false ;
}
};
================================
Best way to download File From Server using java spring and angular js
I think the best way is to make an AJAX request which generates a file on the server. On the browser, when that request completes, use window.open() to download the generated file.
<a target="_self" href="example.com/uploads/asd4a4d5a.pdf" download="foo.pdf">
-----------------------------------Direct File Download and show in new Tab---------------
@RequestMapping (value = "exportPdf/{id}", method=RequestMethod. GET)
public void exportPdf( @PathVariable ("id" ) Long id, HttpServletResponse response) throws IOException{
IOUtils.copy( new FileInputStream( "E:\\SDS-ALL\\nobility-ws\\com.fs\\OASIS_ADMISSION.pdf" ), response.getOutputStream( ) );
response.setContentType( "application/pdf" );
response.setHeader( "Content-Disposition", "attachment; filename=somefile.pdf");
response.flushBuffer( );
}
Open that downloaded file in new Pdf:
< a href ="http://localhost:8080/blog//documents/exportPdf/2" target ="_blank"> Click </a>
Large size file also work in this way:
-------------------------Download Base64 value using Ajax and Show as Data URI------------
@RequestMapping(value = "exportPdfInPost/{id}" , method=RequestMethod.POST )
public @ResponseBody JSONResult exportPdf2( @PathVariable ("id" ) Long id, Document document, HttpServletResponse response) throws IOException{
System. out.println("Document Pojo:" + document);
String pdfBase64 = Base64. encodeBase64String( IOUtils.toByteArray( new FileInputStream( "E:\\SDS-ALL\\nobility-ws\\com.fs\\OASIS_ADMISSION.pdf" )) );
JSONResult result = new JSONResult();
result.setData( "data:application/pdf;base64," +pdfBase64);
return result;
}
Client:
< button class ="btn pull-right" style ="margin-top: 4px" data-ng-click ="downloadPdf();"><i class= "fa fa-file-pdf-o" ></i> Download PDF</ button>
$scope.downloadPdf = function(){
var win = window.open( '', '_blank');
try {
$http.post(getContext() + '/documents/exportPdfInPost/2', {id:'2'}).success(function (data, status, headers, config){
win.location.href = data.data;
});
} catch(e) {
win.close();
return false ;
}
};
Use it for less size file: If file size is too heavy browser will hang as data will be loaded in the browser memory. Still firefox work quite well with heavy size data.
Chrome, safari hang. IE and Opera have no plugin embedded and they cant view even small file.
Safari auto open in new child window and show in Adobe pdf as embedded default.
-------------------------------------------------
If you want to open value in new Tab:
$scope.open = function(docDefinition) {
var win = window.open( '', '_blank');
try {
win.location.href = docDefinition;
} catch(e) {
win.close();
return false ;
}
};
$scope.openPdf = function(){
var docDefinition =data:application/pdf;base64,JVBERi0xLjMKJf////8KOCAwago8lJUVPRgo=" ;
var link = document.createElement( "a");
link.setAttribute( "href", docDefinition);
link.setAttribute( "download", "flowsheet.pdf" );
document.body.appendChild(link)
link.click();
};
-----------------Download file using Ajax:-------------------
var data=data:application/pdf;base64,JVBERi0xLjMKJf////8KOCAwago8lJUVPRgo=" ;
$http.get('http://localhost:8080/blog//documents/exportPdf/2').success(function (data, status, headers, config){
var link = document.createElement("a" );
link.setAttribute( "href", data.data);
link.setAttribute( "download", "flowsheet.pdf" );
document.body.appendChild(link)
link.click();
});
***********************************************************************
Download Any content:
You can do something like this using
Blob
.<a download="content.txt" ng-href="{{ url }}">download</a>
in your controller:
var content = 'file content';var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );
=======================================================================
New Idea:
Better show large size file in new tab without Ajax.
Two step. 1 request to generate file in server and another request to download it.
Lets Do It.
Client:
$scope.downloadPdf = function(){
var win = window.open( '', '_blank');
try {
$http.post(getContext() + '/documents/exportPdfInPost/2', {id:'2'}).success(function (data, status, headers, config){
win.location.href = 'http://localhost:8080/blog//documents/exportPdf/2' ;
win.focus();
});
} catch(e) {
win.close();
return false ;
}
};
First create pdf in the server. and second download it using seperate url.
Server:
@RequestMapping (value = "exportPdf/{id}", method=RequestMethod. GET )
public void exportPdf( @PathVariable ("id" ) Long id, HttpServletResponse response) throwsIOException{
IOUtils. copy( new FileInputStream( "E:\\SDS-ALL\\nobility-ws\\com.fs\\OASIS_ADMISSION.pdf" ), response.getOutputStream( ) );
response.setContentType( "application/pdf" );
response.setHeader( "Content-Disposition" , "attachment; filename=somefile.pdf");
response.flushBuffer( );
}
And
=================================================
Download using get In One Short:
In the get Request: send all the parameters: and then just do this:
var win = window.open('', '_blank');
try {
win.location.href = 'http://localhost:8080/blog//documents/exportPdf/2 ?encodeURIComponent(selected_user.Username) encode params...' ;
win.focus();
} catch(e) {
win.close();
return false ;
}
=================================