多线程(多线程-单例设计模式)

本文深入探讨单例设计模式的饿汉式与懒汉式实现,并通过多线程环境验证其在不同情况下的表现。重点分析了静态初始化与同步代码块在多线程安全编程中的应用,同时比较了两种实现方式的优缺点,提供了在实际项目中选择合适单例模式的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多线程之 单例设计模式
饿汉式 多线程安全代码:
代码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()方法来测试,见效快。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值