Bài giảng Lập trình hướng đối tượng - Tuần 9: Mẫu thiết kế Singleton - Nguyễn Khắc Huy
Mẫu thiết kế Singleton
Nguyễn Khắc Huy
BMCNPM – ĐHKHTN TPHCM
10/2018
1
Thành phần tĩnh
□ Member variables
class PhanSo {
int tuSo;
int mauSo;
public:
PhanSo(int tu, int mau)
}
PhanSo::PhanSo(int tu, int mau) {
this->tuSo = tu;
this->mauSo = mau;
}
void main() {
PhanSo a(1,2); // what do have have?
PhanSo b(3,5); // what do have have?
2}
Thành phần tĩnh
□ Static variable
class PhanSo {
int tuSo;
void main() {
PhanSo a(1, 2); // ??
PhanSo b(3, 5); // ??
int mauSo;
int count = 0;
public:
}
PhanSo(int tu, int mau);
}
PhanSo::PhanSo(int tu, int mau) {
this->tuSo = tu;
this->mauSo = mau;
count++;
}
3
Thành phần tĩnh
□ Static variable
class PhanSo {
PhanSo::count = 0;
void main() {
int tuSo;
int mauSo;
PhanSo a(1, 2); // ??
static int count;
PhanSo b(3, 5); // ??
}
public:
}
PhanSo(int tu, int mau, int count);
PhanSo::PhanSo(int tu, int mau) {
this->tuSo = tu;
this->mauSo = mau;
count++;
}
4
Mẫu thiết kế là gì?
□ Design pattern
5
Sometimes it is important to have only
one instance of a class
□ One printer spooler (though many printers)
□ One file system
□ One window manager
The challenge:
o Ensure that a certain class has only one
instance
o Provide global access to it
6
Question:
How can you prevent any
instances of a class from
being created?
7
Question:
How can you prevent any
instances of a class from
being created?
1. Don’t write it…
2. ?
8
Moving towards a solution…
1. Restrict the ability to construct
more than one instance of a
Singleton class
2. Make the class responsible for
keeping track of its one and onl
instance
3. Provide a global (static) access
method
9
Solution 1: Eager Instantiation
using static initialization
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
// private constructor cannot be called;
// no instances can be created.
private Singleton() {
}
// return the same instance to all callers of this method
public static Singleton getInstance() {
return uniqueInstance;
}
}
10
Important Concepts
1. Why is the constructor private?
Any client that tries to instantiate the Singleton class
directly will get an error at compile time.
ü This ensures that nobody other than the Singleton class and
instantiate the object of this class.
2. How can you access the single instance of the
Singleton class?
getInstance() is a static method. We can use the
class name to reference the method.
ü Singleton.getInstance()
ü This is how we can provide global access to the single instance
of the Singleton class.
11
Eager instantiation has pros and
cons
□ Static initialization is guaranteed to be thread-safe
□ Global/static objects are created whether they are used
or not, as soon as the application is loaded.
□ Creating a Singleton object can be resource intensive
and you may not want to create it until you need it.
□ We might not have all the information to create an
object at static initialization time.
o Example: the kind of file/database/resource that you are
connecting to is usually not known at startup
12
Solution 2: A Lazy Singleton
public class Singleton {
private static Singleton uniqueInstance = null;
static variable to hold the single instance of the class.
private Singleton() {
// construction code goes here.
}
Only this class can instantiate itself.
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
Provides a way to instantiate the class and also provides global access to it.
}
return uniqueInstance;
}
}
13
Lazy initialization
The Singletonclass on the previous slide
uses lazy initialization
oThe uniqueInstanceis not created and
stored in the getInstance()method until it
is first accessed.
public class Singleton {
private static Singleton uniqueInstance = null;
. . .
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
. . .
}
14
Lazy Singletons can have
issues with Multithreading
Thread1
Thread2
Value of
uniqueInstance
Singleton.getInstance()
null
null
Singleton.getInstance()
if (uniqueInstance == null){
null
if (uniqueInstance == null) {
null
uniqueInstance = new
Singleton()
Object 1
return uniqueInstance;
Object 1
Object 2
uniqueInstance = new
Singleton()
return uniqueInstance;
Object 2
15
Another alternative for lazy initialization
public class Singleton {
private static volatile Singleton uniqueInstance =
null;
private Singleton() {
// construction code goes here.
}
public static synchronized Singleton getInstance(){
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
Using the Java keyword synchronized forces every thread to wait
its turn before it can enter the method. This prevents two threads
from entering the method at the same time.
16
The Cost of Synchronization
□ Synchronization is expensive. Synchronized methods
can take 100 times longer to execute than
unsynchronized methods
o This can affect performance of your program if getInstance()
is called frequently
□ Synchronization is relevant only the first time though the
method, so why force repeated usage?
o Once we have set the uniqueInstance to an appropriate
instance, then there is no need to further synchronize the
method.
17
Lazy Initialization Solution 2:
Double Checked Locking
public class Singleton {
private volatile static Singleton uniqueInstance = null;
volatile ensures that the JVM always has an up-to-date value
of uniqueInstance
private Singleton() {
// construction code goes here.
}
Enter a synchronized
block only when there
public static Singleton getInstance() {is no instance.
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
We need to
return uniqueInstance;
synchronize only the
first time through.
}
}
18
Double-checked locking solves
multithreading problems
Thread1
Thread2
Value of
uniqueInstance
Singleton.getInstance()
null
null
Singleton.getInstance()
if (uniqueInstance == null)
null
if (uniqueInstance == null)
null
synchronized (Singleton.class) {
if (uniqueInstance == null)
uniqueInstance = new
Singleton()
Object 1
}
return uniqueInstance;
Object 1
Object 1
synchronized (Singleton.class) {
If (uniqueInstance == null)
// will evaluate to false!!!
return uniqueInstance;
Object 1
The Cost of Double-checked
locking
Code is more complex
o Additional complexity = decreased
maintainability
o Is it worth it?
20
Tải về để xem bản đầy đủ
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng - Tuần 9: Mẫu thiết kế Singleton - Nguyễn Khắc Huy", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
File đính kèm:
bai_giang_lap_trinh_huong_doi_tuong_tuan_9_mau_thiet_ke_sing.pdf

