多线程之 单例设计模式
饿汉式 多线程安全代码:
代码1:
运行结果:
[img]http://dl.iteye.com/upload/picture/pic/132676/9f1bddbf-f6f0-3fd1-a321-405b3427da46.png[/img]
多线程安全性:多线程安全
分析:这种静态初始化的方法是自己被加载时就自己实例化,被形象的称之为饿汉式单例类。而原先的单例模式处理方式要在第一次被引用的时候才会被实例化,就被称为懒汉式单例类。
优缺点:这样导致类加载慢,但运行快。
不安全懒汉式示例:
代码2:
运行结果:
[img]http://dl.iteye.com/upload/picture/pic/132678/cb855529-4881-3aad-bc13-63a5402fd658.png[/img]
懒汉式多线程安全单例类:
代码3:
运行结果:
[img]http://dl.iteye.com/upload/picture/pic/132680/0a4b3310-74a1-3946-8209-6737e6187063.png[/img]
分析:使用了同步代码块,这样每个线程都必须等,当前执行的线程完成操作后才能进去,达到多线程安全编程;可这样也是程序运行效率下降;在同步代码块外在判断一次是否为null,这样程序的运行效率就就会好点了。
同步锁:静态的同步方法,使用的锁是该方法所在类的字节码文件对象,类名.class。
优缺点:加载类快,对象实例延迟加载,第一次运行较慢,还是很不错的。
这个测试有点麻烦,测试好多次才能看到问题,建议大家可以结合使用 线程的sleep()方法来测试,见效快。
饿汉式 多线程安全代码:
代码1:
/**
* 饿汉式
* */
class Single {
private static final Single s = new Single();
private Single(){}
static Single getInstance()
{
return s;
}
public void show()
{
System.out.println(Thread.currentThread().getName()+":"+s);
}
}
class A implements Runnable{
@Override
public void run() {
Single.getInstance().show();
}
}
class Test
{
public static void main(String[] args) {
A a = new A();
Thread b = new Thread(a);
Thread c = new Thread(a);
Thread e = new Thread(a);
Thread f = new Thread(a);
b.start();
try { Thread.sleep(100);} catch (InterruptedException ex) {};
c.start();
try { Thread.sleep(100);} catch (InterruptedException ex) {};
e.start();
try { Thread.sleep(100);} catch (InterruptedException ex) {};
f.start();
}
}
运行结果:
[img]http://dl.iteye.com/upload/picture/pic/132676/9f1bddbf-f6f0-3fd1-a321-405b3427da46.png[/img]
多线程安全性:多线程安全
分析:这种静态初始化的方法是自己被加载时就自己实例化,被形象的称之为饿汉式单例类。而原先的单例模式处理方式要在第一次被引用的时候才会被实例化,就被称为懒汉式单例类。
优缺点:这样导致类加载慢,但运行快。
不安全懒汉式示例:
代码2:
class Single {
private static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s==null)
return s = new Single();
return s;
}
public void show()
{
System.out.println(Thread.currentThread().getName()+":"+s);
}
}
class A implements Runnable{
@Override
public void run() {
Single.getInstance().show();
}
}
class Test
{
public static void main(String[] args) {
A a = new A();
Thread b = new Thread(a);
Thread c = new Thread(a);
Thread e = new Thread(a);
Thread f = new Thread(a);
Thread b1 = new Thread(a);
Thread c1 = new Thread(a);
Thread e1 = new Thread(a);
Thread f1 = new Thread(a);
b.start();
c.start();
e.start();
f.start();
b1.start();
c1.start();
e1.start();
f1.start();
}
}
运行结果:
[img]http://dl.iteye.com/upload/picture/pic/132678/cb855529-4881-3aad-bc13-63a5402fd658.png[/img]
懒汉式多线程安全单例类:
代码3:
/**
* 多线程安全 懒汉式
* */
class Single {
private volatile static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s==null)
{
synchronized (Single.class) {
if(s==null)
return s = new Single();
}
}
return s;
}
public void show()
{
System.out.println(Thread.currentThread().getName()+":"+s);
}
}
class A implements Runnable{
@Override
public void run() {
Single.getInstance().show();
}
}
class Test
{
public static void main(String[] args) {
A a = new A();
Thread b = new Thread(a);
Thread c = new Thread(a);
Thread e = new Thread(a);
Thread f = new Thread(a);
Thread b1 = new Thread(a);
Thread c1 = new Thread(a);
Thread e1 = new Thread(a);
Thread f1 = new Thread(a);
b.start();
c.start();
e.start();
f.start();
b1.start();
c1.start();
e1.start();
f1.start();
}
}
运行结果:
[img]http://dl.iteye.com/upload/picture/pic/132680/0a4b3310-74a1-3946-8209-6737e6187063.png[/img]
分析:使用了同步代码块,这样每个线程都必须等,当前执行的线程完成操作后才能进去,达到多线程安全编程;可这样也是程序运行效率下降;在同步代码块外在判断一次是否为null,这样程序的运行效率就就会好点了。
同步锁:静态的同步方法,使用的锁是该方法所在类的字节码文件对象,类名.class。
优缺点:加载类快,对象实例延迟加载,第一次运行较慢,还是很不错的。
这个测试有点麻烦,测试好多次才能看到问题,建议大家可以结合使用 线程的sleep()方法来测试,见效快。