首先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在单例模式下性能优于多例模式。