Java多线程(七)单例模式与多线程 7.31

立即加载/饿汉模式:

public class MyObject {
//立即加载方式 == 饿汉模式
	private static MyObject myObject = new MyObject();
	private MyObject() {
		
	}
	public static MyObject getInstance() {
		return myObject;
	}
}
public class MyThread extends Thread{
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

延迟加载/懒汉模式:


public class MyObject {
//延迟加载方式 == 懒汉模式
	private static MyObject myObject ;
	private MyObject() {
	}
	public static MyObject getInstance() {
		if (myObject != null) {
		} else {
			myObject = new MyObject();
		}
		return myObject;
	}
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		t1.start();
	}
}
public class MyThread extends Thread{
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}

立即加载  就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接new实例化;

延迟加载  就是在调用get()方法时才被创建,常见的实现办法就是在get()方法中进行new实例化。

延迟加载 的解决方案:(在多线程中无法保持单例)

(1)声明synchronized

(2)尝试代码同步块

(3)针对某些重要的代码进行单独的同步

public class MyObject {
//延迟加载方式 == 懒汉模式
	private static MyObject myObject = new MyObject();
	private MyObject() {
	}
	//设置同步方法效率太低了
	//整个方法被上锁
	//同步代码块,效率也比较低
	//针对某些重要得代码进行单独的同步;
	public static MyObject getInstance() {
		try {
			if (myObject != null) {
			} else {
				Thread.sleep(3000);
				synchronized (MyObject.class) {
					myObject = new MyObject();
				}
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return myObject;
	}
}
public class MyThread extends Thread{
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

(4)使用DCL双检查锁机制

public class MyObject {
//延迟加载方式 == 懒汉模式
	private static MyObject myObject = new MyObject();
	private MyObject() {
	}
	//使用双检测机制来解决问题,既保证了不需要同步代码的异步执行性,又保证了单例的效果;
	public static MyObject getInstance() {
		try {
			if (myObject != null) {
			} else {
				Thread.sleep(3000);
				synchronized (MyObject.class) {
					if (myObject == null) {
						myObject = new MyObject();
					}
				}
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return myObject;
	}
}

public class MyThread extends Thread{
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}

public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

使用静态内部类实现单例模式:

public class MyObject {
//延迟加载方式 == 懒汉模式
	//内部类方式
	private static class MyObjectHandler{
		private static MyObject myObject = new MyObject();
	}
	
	private MyObject() {
	}
	
	public static MyObject getInstance() {
		return MyObjectHandler.myObject;
	}
}

public class MyThread extends Thread{
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

序列化与反序列化的单例模式实现:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SaveAndRead {
	public static void main(String[] args) {
		
		try {
			MyObject myObject = MyObject.getInstance();
			FileOutputStream fosRef = new FileOutputStream(new File("myObjectFile.txt"));
			ObjectOutputStream oosRef = new ObjectOutputStream(fosRef);
			oosRef.writeObject(myObject);
			oosRef.close();
			fosRef.close();
			System.out.println(myObject.hashCode());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			FileInputStream fisRef = new FileInputStream(new File("myObjectFile.txt"));
			ObjectInputStream iosRef = new ObjectInputStream(fisRef);
			MyObject myObject = (MyObject) iosRef.readObject();
			iosRef.close();
			fisRef.close();
			System.out.println(myObject.hashCode());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

import java.io.ObjectStreamException;
import java.io.Serializable;

public class MyObject implements Serializable{
//序列化与反序列化的单例模式的实现
	private static final long serialVersiouUID = 888L;
	private static class MyObjectHandler{
		private static MyObject myObject = new MyObject();
	}
	
	private MyObject() {
	}
	
	public static MyObject getInstance() {
		return MyObjectHandler.myObject;
	}
	protected Object readResolve() throws ObjectStreamException{
		System.out.println("调用了readResolve方法");
		return MyObjectHandler.myObject;
	}
}

使用static代码块实现单例模式:


public class MyObject {
//使用static代码块实现单例模式
	private static MyObject instance = null;
	private MyObject() {
	}
	static {
		instance = new MyObject();
	}
	public static MyObject getInstance() {
		return instance;
	}
}
public class MyThread extends Thread{
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(MyObject.getInstance().hashCode());
		}
	}
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

使用enum枚举数据类型实现单例模式:


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MyObject {
	//使用enum枚举数据类型实现单例模式
	//将枚举类进行暴露,违反了“职责单一原则”
	//完善使用enum枚举数据类型实现单例模式
	public enum MyEnumSingleton{
		connectionFactory;
		private Connection connection;

		private MyEnumSingleton() {

			try {
				System.out.println("调用了MyObject的构造");
				String url = "";
				String username = "";
				String password = "";
				String driverName = "";
				Class.forName(driverName);
				connection = DriverManager.getConnection(url, username, password);
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}


		public Connection getConnection() {
			return connection;
		}
	}
	public static Connection getConnection() {
		return MyEnumSingleton.connectionFactory.getConnection();
	}

}

public class MyThread extends Thread{
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(MyObject.getConnection().hashCode());
		}
	}
	
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值