您的位置:首页 > 职场人生

黑马程序员:java基础——单例设计模式,synchronized及面试常考内容

2014-10-10 10:34 423 查看
-------
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基础——多线程之安全问题与同步


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: