多线程学习笔记(五)---- 扩展知识

一、单例模式中的多线程问题

1、单例模式的俩种情况

单例模式分:饿汉式(先加载的单例设计模式)、懒汉式(延迟加载的单例设计模式)俩种。

2、饿汉式时的多线程问题

public class Single {
	private static final Single s = new Single();
	
	private Single(){}
	
	private static Single getInstance(){
		return s;
	}
}

此模式在多线程下执行getInstance()方法时,是没有安全隐患的。因为它返回的s就是共享变量。

3、懒汉式时的多线程问题

public class SingleDoem {
	private static Single s = null;
	
	private SingleDoem(){}
	
	private static Single getInstance(){
		if(s == null){
			s = new Single();
		}
		return s;
	}
}

此模式在多线程下执行getInstance()方法时,是有安全隐患的。当一个线程刚执行完第7行代码时,第二个线程再执行第7代码时也会进入判断语句中;这样,第一个线程返回的是一个新的Single对象,而第二个线程返回的也是一个新的Single对象,这就违法了单例设计模式。

4、解决懒汉式时的多线程问题

  • 在延迟加载模式的getInstance方法上加synchronized关键字即可
public class SingleDoem {
	private static Single s = null;
	
	private SingleDoem(){}
	
	private static synchronized Single getInstance(){
		if(s == null){
			s = new Single();
		}
		return s;
	}
}

但这个办法是以牺牲效率来拯救多线程的安全。下面的方法,可以在保证多线程安全的情况下,再提示效率

  • 使用同步代码,并在其之前进行判断
public class SingleDoem {
	private static Single s = null;
	
	private SingleDoem(){}
	
	private static Single getInstance(){
		if(s == null){
			synchronized (SingleDoem.class) {
				if(s == null){
					s = new Single();
				}
			}
		}
		return s;
	}
}

总结:“synchronized (SingleDoem.class)”是为了多线程安全;
第一个“if(s == null)”=是用于拯救效率;

二、多线程相关面试题

1、以下代码会打印的语句是?

class Thread{
    public static void mian(String[] args){
        new Thread(new Runnable(){
            public void run(){
                System.out.println("runnable run");
            }
        }){
            public void run(){
                System.out.println("subThread run");
            }
        }.start();
}

答:以子类为主。即,subThread run。然后是Runnale的run()方法,最后是Thread自己的run()方法。

2、以下代码在编译的时候,是否会出现错误?如果会,错误出现在哪行?

class Test implements Runnable{
    public void run(Thread t){
    
	}
}

答:会出错,错误在第一行。因为未实现Runnable接口的run()方法。

你可能感兴趣的:(多线程学习笔记(五)---- 扩展知识)