首先ObjectMapper如果是線程安全的才能使用單例模式,測試表明它是線程安全的。
接下來進行單例模式和多例模式的性能測試,每個模式都測試兩輪(單線程,多線程)。
單例模式
import cn.ec.entity.AgentEntity;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.concurrent.CountDownLatch;
/**
* 測試Jackson的ObjectMapper性能
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestJackSonIsSingle {
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 單例模式
*
* @return
*/
private ObjectMapper getObjectMapper() {
return objectMapper;
}
/**
* 單線程模式
*
* @throws JsonProcessingException
*/
@Test
public void testSingleThread() throws JsonProcessingException {
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
getObjectMapper().writeValueAsString(
new AgentEntity().setId(i).setName(String.valueOf(i))
);
}
System.out.println("最終用時:" + (System.currentTimeMillis() - start) + "ms");//30,14,14,平均值:19.33
}
/**
* 多線程模式
*
* @throws InterruptedException
*/
@Test
public void testMulThread() throws InterruptedException {
final int count = 100;
CountDownLatch countDownLatch = new CountDownLatch(count);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
int finalI = i;
new Thread(() -> {
try {
getObjectMapper().writeValueAsString(
new AgentEntity().setId(finalI).setName(String.valueOf(finalI))
);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("最終用時:" + (System.currentTimeMillis() - start) + "ms");//79,153,67,平均值:99.66
}
}
測試結果
- 單線程19.33毫秒
- 多線程99.66毫秒
多例模式
import cn.ec.entity.AgentEntity;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.concurrent.CountDownLatch;
/**
* 測試Jackson的ObjectMapper性能
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestJackSonIsSingle {
/**
* 多例模式
*
* @return
*/
private ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
/**
* 單線程模式
*
* @throws JsonProcessingException
*/
@Test
public void testSingleThread() throws JsonProcessingException {
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
getObjectMapper().writeValueAsString(
new AgentEntity().setId(i).setName(String.valueOf(i))
);
}
System.out.println("最終用時:" + (System.currentTimeMillis() - start) + "ms");//153,125,135,平均值:137.66
}
/**
* 多線程模式
*
* @throws InterruptedException
*/
@Test
public void testMulThread() throws InterruptedException {
final int count = 100;
CountDownLatch countDownLatch = new CountDownLatch(count);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
int finalI = i;
new Thread(() -> {
try {
getObjectMapper().writeValueAsString(
new AgentEntity().setId(finalI).setName(String.valueOf(finalI))
);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("最終用時:" + (System.currentTimeMillis() - start) + "ms");//225,173,161,平均值:186.33
}
}
測試結果
- 單線程137.66毫秒
- 多線程186.33毫秒
結論
模式 | 單線程耗時(ms) | 多線程耗時(ms) |
---|---|---|
單例模式 | 19.33 | 99.66 |
多例模式 | 137.66 | 186.33 |
測試證明:不管是多線程還是單線程,Jackson的ObjectMapper在單例模式下性能優於多例模式。