• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.misc;
2 
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Date;
6 import java.util.List;
7 import java.util.concurrent.*;
8 import java.util.concurrent.atomic.AtomicInteger;
9 
10 import com.fasterxml.jackson.databind.*;
11 
12 public class ThreadSafety1759Test extends BaseMapTest
13 {
14     /*
15     /**********************************************************
16     /* Test methods
17     /**********************************************************
18      */
19 
testCalendarForDeser()20     public void testCalendarForDeser() throws Exception
21     {
22         final ObjectMapper mapper = newJsonMapper();
23 
24         final int numThreads = 4;
25         final int COUNT = 3000;
26         final AtomicInteger counter = new AtomicInteger();
27 
28         // IMPORTANT! Use different timestamp for every thread
29         List<Callable<Throwable>> calls = new ArrayList<Callable<Throwable>>();
30         for (int thread = 1; thread <= numThreads; ++thread) {
31             final String json = quote(String.format("2017-01-%02dT16:30:49Z", thread));
32             final long timestamp = mapper.readValue(json, Date.class).getTime();
33 
34             calls.add(createCallable(thread, mapper, json, timestamp, COUNT, counter));
35         }
36 
37         ExecutorService executor = Executors.newFixedThreadPool(numThreads);
38         List<Future<Throwable>> results = new ArrayList<>();
39         for (Callable<Throwable> c : calls) {
40             results.add(executor.submit(c));
41         }
42         executor.shutdown();
43         for (Future<Throwable> f : results) {
44             Throwable t = f.get(5, TimeUnit.SECONDS);
45             if (t != null) {
46                 fail("Exception during processing: "+t.getMessage());
47             }
48         }
49         assertEquals(numThreads * COUNT, counter.get());
50     }
51 
createCallable(final int threadId, final ObjectMapper mapper, final String json, final long timestamp, final int count, final AtomicInteger counter)52     private Callable<Throwable> createCallable(final int threadId,
53             final ObjectMapper mapper,
54             final String json, final long timestamp,
55             final int count, final AtomicInteger counter)
56     {
57         return new Callable<Throwable>() {
58             @Override
59             public Throwable call() throws IOException {
60                 for (int i = 0; i < count; ++i) {
61                     Date dt = mapper.readValue(json, Date.class);
62                     if (dt.getTime() != timestamp) {
63                         return new IllegalArgumentException("Wrong timestamp (thread id "+threadId+", input: "+json+": should get "+timestamp+", got "+dt.getTime());
64                     }
65                     counter.addAndGet(1);
66                 }
67                 return null;
68             }
69         };
70     }
71 }
72