Java thread-safe example

Ví dụ về thread-safe trong Java , với 1 built-in class khá thường gặp là SimpleDateFormat .

(Ở đây viết dạng chạy với JUnit4 , ai chưa quen có thể copy lại thành hàm main() để chạy)

  public void testFormattingWithRunnable() {
    // FIXME - dq: To see the bug, use SimpleDateFormat statement
    final java.text.DateFormat df = new java.text.SimpleDateFormat("dd-MMM-yyyy");
    // final DateFormatter df = new vn.ducquoc.util.DateFormatter("dd-MMM-yyyy");
    final String[] testdata = { "01-Jan-1999", "14-Feb-2001", "31-Dec-2007" };
    Runnable runnables[] = new Runnable[testdata.length];
    org.junit.Assert.assertNotNull("Look at the results");
    for (int i = 0; i < runnables.length; i++) {
      final int i2 = i;
      runnables[i] = new Runnable() {
        public void run() {
          try { // 42 here, may adjust 12->120 depending on your computer
            for (int j = 0; j < 42; j++) {
              String str = testdata[i2];
              String str2 = null;
              /* synchronized(df) */{
                Date d = df.parse(str);
                str2 = df.format(d);
              System.out.println("EXPECTED " + str + " ACTUAL " + str2);
          } catch (java.text.ParseException e) {
            throw new RuntimeException("Parse failed");
      new Thread(runnables[i]).start();




Không chỉ Thread/Runnable bị vấn đề mà ngay cả các Callable cũng rứa:

  public void testParsingWithCallable() throws Exception {

    // FIXME - dq: To see the bug, use SimpleDateFormat statement
    final java.text.DateFormat df = new java.text.SimpleDateFormat("yyyyMMdd");
    // final DateFormatter df = new vn.ducquoc.util.DateFormatter("yyyyMMdd");

    Callable<Date> task = new Callable<Date>() {
      public Date call() throws Exception {
        return df.parse("20101010");

    // pool with 5 threads
    ExecutorService exec = Executors.newFixedThreadPool(5);
    List<Future<Date>> results = new ArrayList<Future<Date>>();

    // perform 42 date conversions, may adjust 12->120 depending on your computer
    for (int i = 0; i < 42; i++) {

    org.junit.Assert.assertNotNull("Look at the results");
    for (Future<Date> result : results) {







Các cách chính để tránh vấn đề cho multi-thread (concurrency) :

1/ dùng từ khóa synchronized của Java cho block hoặc method


2/ tạo một đối tượng mới mỗi khi thực hiện tác vụ (bằng cách new , clone() , Class.newInstance() , … )


3/ dùng các biến thuộc lớp ThreadLocal của Java



Theo nguyên lý K.I.S.S/Y.A.G.N.I thì có lẽ nên áp dụng cách 1 .





A coder, husband and brother...
This entry was posted in Coding, Marketing. Bookmark the permalink.

5 Responses to Java thread-safe example

  1. Actually, there is one or more other approaches, which are the ‘lower level’ of above approaches. For example, instead of ‘synchronized’ block we can use Lock of java.util.concurrent, such as ReentrantLock. Or use some AtomicInteger, AtomicReference instead of ThreadLocal. Or use ‘partial instances’ by getDateInstance() with some cache like ConcurrentHashMap (and maybe SoftReference/WeakReference)

    These ‘low-level’ approach is suitable when you want to know more about underlying techniques to handle the multi-thread, like mutex, semaphore, blockingQueue, nonBlocking algorithms… or when it (really) reaches the phase of performance optimization . The most use case is, to impress some guys who don’t even know “synchronized”, such as a non-technical manager :- ) .

  2. Pingback: Logging best practices | DucQuoc's Blog

  3. Pingback: Sprint end DoW | DucQuoc's Blog

  4. Pingback: Sprint end DoW | DucQuoc's Blog

  5. As of Java 8+ (i.e. JDK/JRE version 8 and later), we should use DateTimeFormatter to format/parse to `LocalDateTime/LocalDate`, instead of `SimpleDateFormat` to Date.

    DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

    Sample test class:

    DateTimeFormatter and java.time.* package in general was inspired from “joda time” library, which is considered as “ported” from Joda time in to JDK as of Java 8. It has better API (fluent interface, intuitive, thread-safe, etc…) compared to old SimpleDateFormat.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s