java多线程编程学习chapter6

单例模式和多线程

解决问题:如何使单例模式遇到多线程是安全的,正确的

1.立即加载/饿汉模式
在方法调用前,实例已经创建好
package com.nineclient.call.chapter6.singleton;

public class Run1 {

	public static void main(String[] args) {
		ThreadA a1 = new ThreadA();
		ThreadA a2 = new ThreadA();
		ThreadA a3 = new ThreadA();
		a1.start();
		a2.start();
		a3.start();
		
	}
	
}

class ThreadA extends Thread {
	public void run() {
		System.out.println(MyService.getMyService().hashCode());
	}
}

class MyService {
	private static MyService service = new MyService();
	
	private MyService(){
		
	}
	
	public static MyService getMyService() {
		return service;
	}

}

2.延迟加载/懒汉模式
调用方法时,实例已经创建好
package com.nineclient.call.chapter6.singleton;

public class Run2 {

	public static void main(String[] args) {
		Thread1 a = new Thread1();
		a.start();
		/*Thread1 a1 = new Thread1();
		a1.start();
		Thread1 a2 = new Thread1();
		a2.start();*/
	}
}

class MyService1 {
	private static MyService1 service;
	private MyService1(){}
	public static MyService1 getMyService1() {
		if(service == null) {
			service = new MyService1();
		}
		return service;
	}
}

class Thread1 extends Thread {
	public void run() {
		System.out.println(MyService1.getMyService1().hashCode());
	}
}

当多线程的时候,取得值有可能会不一样

3.延迟加载的解决方案
就是在get方法上加上synchronized
package com.nineclient.call.chapter6.singleton;

public class Run3 {

	public static void main(String[] args) {
		Thread2 a = new Thread2();
		a.start();
		Thread2 a1 = new Thread2();
		a1.start();
		Thread2 a2 = new Thread2();
		a2.start();
	}
}

class MyService2 {
	private static MyService2 service;
	private MyService2(){}
	public synchronized static MyService2 getMyService2() {
		if(service == null) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			service = new MyService2();
		}
		return service;
	}
}

class Thread2 extends Thread {
	public void run() {
		System.out.println(MyService2.getMyService2().hashCode());
	}
}

这种情况在要求效率比较高的时候,可以使用同步代码块
package com.nineclient.call.chapter6.singleton;

public class Run4 {

	public static void main(String[] args) {
		Thread4 a = new Thread4();
		a.start();
		Thread4 a1 = new Thread4();
		a1.start();
		Thread4 a2 = new Thread4();
		a2.start();
	}
}

class MyService4 {
	private static MyService4 service;
	private MyService4(){}
	public static MyService4 getMyService4() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		synchronized (MyService4.class){
			if(service == null) {
			    service = new MyService4();
			}
		}
			
		return service;
	}
}

class Thread4 extends Thread {
	public void run() {
		System.out.println(MyService4.getMyService4().hashCode());
	}
}

4.使用静态内置类实现单例模式
package com.nineclient.call.chapter6.singleton;

public class Run5 {
	public static void main(String[] args) {
		Thread5 a = new Thread5();
		a.start();
		Thread5 a1 = new Thread5();
		a1.start();
		Thread5 a2 = new Thread5();
		a2.start();
	}

}

class MyService5 {
	private static class MyService5Handle{
		private static MyService5 service = new MyService5();
	}
	private MyService5() {
		
	}
	
	public static MyService5 getMyService5() {
		return MyService5Handle.service;
	}
	
}

class Thread5 extends Thread {
	public void run() {
		System.out.println(MyService5.getMyService5().hashCode());
	}
}

5.如果是序列化对象,默认方式运行,还是会出现多例
解决办法是在反序列化中使用readResolve()方法

6.使用静态代码块实现单例模式
package com.nineclient.call.chapter6.singleton;

public class Run6 {

	public static void main(String[] args) {
		Thread6 a = new Thread6();
		a.start();
		Thread6 b = new Thread6();
		b.start();
		Thread6 c = new Thread6();
		c.start();
		
	}
}

class MyService6 {

	private static MyService6 service;
	private MyService6() {
		
	}
	static {
		service = new MyService6();
	}
	public static MyService6 getMyService() {
		return service;
	}

}

class Thread6 extends Thread{
	public void run() {
		System.out.println(MyService6.getMyService().hashCode());
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值