黑马程序员:java基础——单例设计模式,synchronized及面试常考内容,synchronized常考
黑马程序员:java基础——单例设计模式,synchronized及面试常考内容,synchronized常考
------- Java EE培训、java培训、期待与您交流! ----------
1.概念
设计模式:解决某一类问题最行之有效的方法。
java中23种设计模式:
单例设计模式:解决一个类在内存中只存在一个对象。
想要保证对象唯一:
1.为了避免其他程序过多建立该类的对象,先禁止其他程序建立该类对象
2.为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
这三部用代码体现的方式:
1.将构造函数私有化
2.在类中创建一个本类对象
3.提供一个方法可以获取到该对象
对于事物该怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
2.单例设计模式
单例设计模式有两种:
2.1 饿汉式
代码如下:
class Single{
private Single(){}
private static final Single s = new Single();
public static Single getInstance(){
return s;
}
}
先初始化对象。称为饿汉式。Single类一进内存就创建好了对象。
现实开发中常用的是饿汉式。
2.2 懒汉式
对象是方法被调用时,才初始化,也叫做对象的延时加载。称为懒汉式。
代码如下:
class Singleton{
private static Singleton s=null;
private Singleton(){}
public static Singleton getInstance(){
if(s==null){
synchronized(Singleton.class){
if(s==null){
s = new Singleton();
}
}
}
return s;
}
}
注意关键字sychronized,这个关键字代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法,有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
3.面试考查点
1.单例设计模式中懒汉式和饿汉式有什么区别?
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不会再改变。(final关键字的原因)
懒汉式在类创建时不会先创建对象,而在使用的时候才会去创建对象,具有实例延迟加载的作用。但是如果在创建实例对象时不加上synchronized(同步锁)则会导致对对象的访问不是线程安全的。
2.单例设计模式中懒汉式安全吗?如何解决?
不安全,如果多线程访问时会出现安全问题。解决方法是使用synchronized同步锁。使用方法有两种:synchronized 方法和 synchronized 块。
3.加载同步锁时会不会出现问题,如何解决?
在加载同步锁的时候会出现低效。可以用双重判断的方法可以解决效率问题。
4.加载同步锁的时候使用的锁是哪一个?
叫做该类所属的字节码对象。即 类名.class。
4.synchronized关键字
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。
解决办法就是对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。
Java对于多线程的安全问题提供了专业的解决方式,就是同步代码块,即synchronized 关键字。
synchronized(对象){
需要被同步的代码
}
对象如同锁,持有锁的线程可以在同步中执行。没有持有锁的线程即使获取到CPU的执行权也无法进入,因为没有获取到锁。
这个关键字的使用代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法,有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
同步的前提:
1.必须要有两个或者两个以上的线程
2.必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题
弊端:多个线程都需要判断锁,较为消耗资源
需要注意的是:
非静态函数需要被对象调用,那么函数都有一个所属对象引用,就是this。所以同步函数使用的锁是this。
静态的同步方法,使用的锁是该方法所在类的字节码文件对象,也就是类名.class
代码参见:黑马程序员:Java基础——多线程之安全问题与同步
相关文章
- 暂无相关文章
用户点评