单例模式一般写法有多种,那么哪种相对来说效果比较好。下面一起看看我的测试结果吧。
我是通过CountDownLatch来模拟刚并发下,各种单例模式的执行结果。自己做加深影响所写,所以写的比较粗糙,希望大家不要介意。
先上代码吧,后面做结果说明
1、最基础的单例
package singleton;
/**
* 最简单的单例
*/
public class MySingleton {
private static MySingleton mySingleton = null;
public static MySingleton getInstance(){
if(mySingleton == null){
System.out.println(System.currentTimeMillis());
mySingleton = new MySingleton();
}
return mySingleton;
}
}
2、带锁的单例
package singleton;
/**
* 最简单的单例
*/
public class MySingleton2 {
private static MySingleton2 mySingleton = null;
private static Object obj = new Object();
public static MySingleton2 getInstance(){
if(mySingleton == null){
System.out.println(System.currentTimeMillis());
synchronized (obj){
if(mySingleton == null){
mySingleton = new MySingleton2();
}
}
}
return mySingleton;
}
}
3、测试最简单的单例类
package singleton;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 测试类
*/
public class Test {
/**
* 模拟client_num个客户端同时访问
*/
private static int clientNum = 1000;
private static int threadsNum = 10;
/**
* 计数器
*/
final static CountDownLatch doneSignal = new CountDownLatch(clientNum);
public static void main(String[] args) {
/**
* 建立线程池
*/
ExecutorService exec = Executors.newFixedThreadPool(threadsNum);
for(int i=0 ; i< clientNum; i++){
MyRunnable myRunnable = new MyRunnable();
exec.execute(myRunnable);
doneSignal.countDown();
}
}
static class MyRunnable implements Runnable{
@Override
public void run() {
try{
doneSignal.await();
}catch (Exception e){
e.printStackTrace();
}
System.out.println(MySingleton.getInstance()+"=");
}
}
}
测试结果:
4、上锁的单例测试类
package singleton;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 测试类
*/
public class Test {
/**
* 模拟client_num个客户端同时访问
*/
private static int clientNum = 100;
private static int threadsNum = 5;
/**
* 计数器
*/
final static CountDownLatch doneSignal = new CountDownLatch(clientNum);
public static void main(String[] args) {
/**
* 建立线程池
*/
ExecutorService exec = Executors.newFixedThreadPool(threadsNum);
for(int i=0 ; i< clientNum; i++){
MyRunnable myRunnable = new MyRunnable();
exec.execute(myRunnable);
doneSignal.countDown();
}
}
static class MyRunnable implements Runnable{
@Override
public void run() {
try{
doneSignal.await();
}catch (Exception e){
e.printStackTrace();
}
System.out.println(MySingleton2.getInstance()+"=");
}
}
}
测试结果: