单例从概念上讲: 一个JVM里,只能有一个实例 多线程,仍旧是基于同一进程下,自然也是基于同一JVM下,因此符合单例的概念.
1.多实例多线程
单例类: public class MySingleton1 { private static final MySingleton1 instance =new MySingleton1(); private MySingleton1(){} public static MySingleton1 getInstance() { return instance; } }
|
线程类:run()方法里面调用单例 public void run(){ MySingleton1 mySingleton1=null; mySingleton1 = MySingleton1.getInstance(); System.out.println(mySingleton1+":"+mySingleton1.hashCode()); }
|
测试代码:起10个线程,每个线程都是一个单独的实例 for(int i=0;i<10;i++){ Thread t = new Thread(new MyThread(),String.valueOf(i)); t.start(); }
|
看结果: 证明多线程多实例下,获取的确实是同一实例 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574 com.machome.singleton.MySingleton1@ca0b6:827574
| 2.单实例多线程
单例类和线程类都不变
|
就测试代码改一下,起10个线程,都引用同一实例 MyThread myThread= new MyThread(); for(int i=0;i<10;i++){ Thread t = new Thread(myThread,String.valueOf(i)); t.start(); }
|
看结果: com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396 com.machome.singleton.MySingleton1@1b67f74:28737396
|
有状态单例 public class MySingleton1 { private static final MySingleton1 instance =new MySingleton1();
private MySingleton1(){} public static MySingleton1 getInstance() { return instance; }
// 状态 private String name; private int age; public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; } }
|
线程类: 在线程中获取单例,并且在第1号线程和第5号线程分别改变单例的状态 public class MyThreadForStateful implements Runnable{ public void run(){ MySingleton1 mySingleton1=null; mySingleton1 = MySingleton1.getInstance(); if(Thread.currentThread().getName().equals("1")){ mySingleton1.setName("mac"); mySingleton1.setAge(11); }else if(Thread.currentThread().getName().equals("5")){ mySingleton1.setName("silly"); mySingleton1.setAge(22); } System.out.println(Thread.currentThread().getName() +":"+mySingleton1+":" +mySingleton1.getName()+mySingleton1.getAge()); } }
|
测试代码: for(int i=0;i<10;i++){ Thread t = new Thread(new MyThreadForStateful(),String.valueOf(i)); t.start(); }
执行效果: 证明单例的状态是被多实例共享的 0:com.machome.singleton.MySingleton1@ca0b6:null0 1:com.machome.singleton.MySingleton1@ca0b6:mac11 2:com.machome.singleton.MySingleton1@ca0b6:mac11 3:com.machome.singleton.MySingleton1@ca0b6:mac11 4:com.machome.singleton.MySingleton1@ca0b6:mac11 5:com.machome.singleton.MySingleton1@ca0b6:silly22 6:com.machome.singleton.MySingleton1@ca0b6:silly22 7:com.machome.singleton.MySingleton1@ca0b6:silly22 8:com.machome.singleton.MySingleton1@ca0b6:silly22 9:com.machome.singleton.MySingleton1@ca0b6:silly22
| 结论:只要多线程能成功获取单例(即多线程获得的单例实例是相同的),必然能共享单例的状态
|