- my webspace

- my webspace

Latest Comment

Why I must believe in GOD
Testing time is almost passed..there are many colours in lif...
27/06/12 01:43 More...
By Tarun Shekhawat

Allama Iqbal - Selective verse...
Yahoouj
Really good work about this website was done. Keep trying mo...
07/03/10 15:04 More...
By Roderick

Allama Iqbal - Selective verse...
Great Job
You have dont a great job of collecting these... Even I had ...
25/08/09 01:01 More...
By Sikandar

O ye who don't believe !
It's like Lehman Brothers :grin
11/10/08 10:31 More...
By anurag Chaturvedi

I Protest
@Sikku
Thanks Sikku for the feedback. I never intend to blame, a...
29/07/08 11:06 More...
By Aminur Rashid

Login






Lost Password?
Home arrow Java arrow Thread unsafe Format in Java
Thread unsafe Format in Java PDF Print E-mail
User Rating: / 0
PoorBest 
Written by Aminur Rashid   
Tuesday, 12 April 2011


Recently I was asked by one of our team mate that during load testing, order creation was failing (One of the application I am working on is an Order Management Application) because of wrong inputs. However, the unit tests, with the same input was working fine. Investigation into it, led to (once again) an old jdk "designed" bug 4146524 (or feature). After seeing such issues in a number of applications, I am sure a number of developers are yet not aware of Format objects are not thread-safe. So if you create a Format object (or a MessageFormat, NumberFormat, DecimalFormat, ChoiceFormat, DateFormat or SimpleDateFormat object), it cannot be shared among threads.

A number of write ups are available on internet to make sure your Format objects can work on multi threaded environment. Recreating it below, if it can help some :

Thread unsafe implementation
package aminur.test.formatters;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;

public final class ThreadUnsafePriceFormatter {
	// the price formats
	private static final DecimalFormat pointSeparatedFormat;

	static {
		DecimalFormatSymbols symbols = new DecimalFormatSymbols();
		symbols.setDecimalSeparator('.');
		pointSeparatedFormat = new DecimalFormat("#0.00", symbols);
	}
	private ThreadUnsafePriceFormatter() {
	}
	public static String formatPointSeparated(double price) {
		return pointSeparatedFormat.format(price);
	}
	public static Number parsePointSeparated(String price)
			throws ParseException {
		return pointSeparatedFormat.parse(price);
	}
}


Problem, In multi-threaded environment, it can even throw exception.
private static void testThreadUnSafeFormatter() throws Exception {
		Callable<Number> task = new Callable<Number>() {
			public Number call() throws Exception {
				return ThreadUnsafePriceFormatter.parsePointSeparated("2.2");
			}
		};
		executeTasks(task);
}
private static void executeTasks(final Callable<Number> task)
			throws Exception {
		ExecutorService exec = Executors.newFixedThreadPool(100);
		List<Future<Number>> results = new ArrayList<Future<Number>>();
		for (int i = 0; i < 150; i++) {
			results.add(exec.submit(task));
		}

		exec.shutdown();

		for (Future<Number> result : results) {
			System.out.println(result.get());
		}
}
Thread safe implementation

I used the most recommended method ThreadLocal to provide a thread based copy of Format object.
package aminur.test.formatters;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;

public class ThreadSafePriceFormatter {
	// the price formats
	private static final ThreadLocal<DecimalFormat> pointSeparatedFormat = new ThreadLocal<DecimalFormat>() {
		@Override
		protected DecimalFormat initialValue() {
			DecimalFormatSymbols symbols = new DecimalFormatSymbols();
			symbols.setDecimalSeparator('.');
			return (new DecimalFormat("#0.00", symbols));
		}
	};
	private ThreadSafePriceFormatter() {
	}
	public static String formatPointSeparated(double price) {
		return pointSeparatedFormat.get().format(price);
	}
	public static Number parsePointSeparated(String price)
			throws ParseException {
		return pointSeparatedFormat.get().parse(price);
	}
}



Java Specialist, Dr. Heinz M. Kabutz suggests using ThreadLocal with SoftReference.Some have also suggested to use Joda-Time



StumbleUponDigg This!Bookmark on Delicious

Add as favourites (449) | Quote this article on your site | Views: 6397 | E-mail

Be first to comment this article
RSS comments

Only registered users can write comments.
Please login or register.

Last Updated ( Tuesday, 12 April 2011 )
 
< Prev   Next >
Aminur Rashid