JAVA 가 단일 모드 를 파괴 하 는 방식 및 피 하 는 방법
똑똑 한 너 는 이런 질문 을 보고 답 이 NO 라 는 것 을 알 아 맞 혔 을 것 이다.여기 서 필 자 는 뜸 을 들 이지 않 고 단도직입적으로 말 하 자!실제로 일부 장면 에서 프로그램 처리 가 부당 하면 단일 모델 을 무정 하 게 파괴 하여 프로그램 에 여러 개의 인 스 턴 스 대상 이 나타 날 수 있다.
다음은 필자 가 이미 알 고 있 는 세 가지 사례 모델 을 파괴 하 는 방식 과 피 하 는 방법 을 소개 한다.
1.단일 모델 에 대한 파 괴 를 반사 한다.
우 리 는 먼저 하나의 예 를 통 해 직관 적 으로 느껴 보 자.
(1)사례
DCL 에서 실 현 된 단일 모드:
public class Singleton{
private static volatile Singleton mInstance;
private Singleton(){}
public static Singleton getInstance(){
if(mInstance == null){
synchronized (Singleton.class) {
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
테스트 코드:
public class SingletonDemo {
public static void main(String[] args){
Singleton singleton = Singleton.getInstance();
try {
Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
Singleton reflectSingleton = constructor.newInstance();
System.out.println(reflectSingleton == singleton);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
실행 결과:false
실행 결 과 는 반사 적 인 방식 으로 이 종 류 를 다른 경로 로 만 들 었 기 때문에 프로그램 에 하나의 사례 만 존재 하 는 것 이 아니 라 는 것 을 설명 한다.
(2)해결 방안
그 사상 은 하나의 전역 변 수 를 사용 하여 이미 실례 화 되 었 는 지 여 부 를 표시 하 는 것 이다.만약 에 이미 실례 화 되 었 다 면 두 번 째 실례 화 될 때 이상 을 던 지 는 것 이다.구현 코드 는 다음 과 같 습 니 다:
public class Singleton{
private static volatile Singleton mInstance;
private static volatile boolean mIsInstantiated = false;
private Singleton(){
if (mIsInstantiated){
throw new RuntimeException("Has been instantiated, can not do it again!");
}
mIsInstantiated = true;
}
public static Singleton getInstance(){
if(mInstance == null){
synchronized (Singleton.class) {
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
실행 결과:2.clone()의 단일 모드 파괴
하나의 예 를 들 어 clone()을 허용 해 야 할 때 잘못 처리 하면 프로그램 에 하나의 인 스 턴 스 만 나타 날 수 있 습 니 다.
(1)사례
Cloneable 인터페이스 단일 클래스 구현:
public class Singleton implements Cloneable{
private static volatile Singleton mInstance;
private Singleton(){
}
public static Singleton getInstance(){
if(mInstance == null){
synchronized (Singleton.class) {
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
테스트 코드:
public class SingletonDemo {
public static void main(String[] args){
try {
Singleton singleton = Singleton.getInstance();
Singleton cloneSingleton;
cloneSingleton = (Singleton) Singleton.getInstance().clone();
System.out.println(cloneSingleton == singleton);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
실행 결과:false
(2)해결 방안:
해결 사상 은 clone()방법 을 다시 쓰 고 clone()을 바 꿀 때 이미 인 스 턴 스 된 대상 으로 돌아 가 는 것 이다.
public class Singleton implements Cloneable{
private static volatile Singleton mInstance;
private Singleton(){
}
public static Singleton getInstance(){
if(mInstance == null){
synchronized (Singleton.class) {
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return mInstance;
}
}
실행 결과:true
3.단일 모델 에 대한 직렬 화 파괴
직렬 화/반 직렬 화 를 사용 할 때 도 새로운 인 스 턴 스 대상 이 발생 하 는 경우 가 있다.
(1)사례
직렬 화 인 터 페 이 스 를 실현 한 단일 클래스:
public class Singleton implements Serializable{
private static volatile Singleton mInstance;
private Singleton(){
}
public static Singleton getInstance(){
if(mInstance == null){
synchronized (Singleton.class) {
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
테스트 코드:
public class SingletonDemo {
public static void main(String[] args){
try {
Singleton singleton = Singleton.getInstance();
FileOutputStream fos = new FileOutputStream("singleton.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(singleton);
oos.close();
fos.close();
FileInputStream fis = new FileInputStream("singleton.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Singleton serializedSingleton = (Singleton) ois.readObject();
fis.close();
ois.close();
System.out.println(serializedSingleton==singleton);
} catch (Exception e) {
e.printStackTrace();
}
}
}
실행 결과:false
(2)해결 방안
역 직렬 화 시 리 셋 방법 readResolve()에서 단일 대상 을 되 돌려 줍 니 다.
public class Singleton implements Serializable{
private static volatile Singleton mInstance;
private Singleton(){
}
public static Singleton getInstance(){
if(mInstance == null){
synchronized (Singleton.class) {
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
protected Object readResolve() throws ObjectStreamException{
return mInstance;
}
}
결과:true
이상 은 필자 가 현재 알 고 있 는 세 가지 사례 모델 을 파괴 할 수 있 는 장면 과 대응 하 는 해결 방법 이다.독자 가 다른 장면 이 있다 는 것 을 알 면 반드시 공유 해 야 한다.바로'독 락 락 은 대중 락 보다 못 하 다'는 것 이다!!
단 례 모델 은 디자인 모델 중 가장 간단 한 것 으로 보이 지만'참 새 는 작 지만 오장 이 모두 갖 추어 져 있다'.그 중에서 많은 세부 사항 은 깊이 연구 할 만 한 것 이다.본 편 에서 소개 한 이 몇 가지 장면 도 줄 거 리 를 소 개 했 을 뿐 많은 세부 사항 은 독자 스스로 실험 하고 퇴고 해 야 한다.예 를 들 어 매 거 진 방식 으로 단일 모델 을 실현 하면 상기 문제 가 존재 하지 않 고 다른 실현 방식 은 모두 상기 문제 가 존재 하 는 것 같다.
후기
본 편 은 다음 과 같은 자 료 를 표절 하 였 다.
이상 은 JAVA 가 단일 모델 을 파괴 하 는 방식 과 피 하 는 방법 에 대한 상세 한 내용 입 니 다.JAVA 단일 모델 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.