恰好说GCD

材料借鉴:http://cantellow.iteye.com/blog/838473

讲到iOS多线程,一般还会谈及四种方式:pthread、NSThread、GCD和NSOperation。其中,苹果推荐呢是我们最为常使用的确实是GCD。对于身为开发者的我们来说,并发一直还怪困难,如果对GCD的理解不敷透彻,那么iOS开发的历程绝对免会见一帆风顺。这里,我会从几单角度浅谈自身本着GCD的领悟。

简言之介绍:

同一、多线程背景

Although threads have been around for many years and continue to have
their uses, they do not solve the general problem of executing
multiple tasks in a scalable way. With threads, the burden of creating
a scalable solution rests squarely on the shoulders of you, the
developer. You have to decide how many threads to create and adjust
that number dynamically as system conditions change. Another problem
is that your application assumes most of the costs associated with
creating and maintaining any threads it uses.

上述大致说发了直白操纵线程实现多线程的害处:

  • 开发人员必须依据系统的转动态调整线程的数码和状态,即针对开发者的承负重。
  • 应用程序会当创立与护卫线程上淘过多资产,即效率不如。

相对的,GCD是平等套小层级的C API,通过
GCD,开发者只需要往行中上加同段子取代码块(block或C函数指针),而不需要直接与线程打交道。GCD在后端管理方一个线程池,它不光控制在若的代码块用以哪个线程被实施,还根据可用的系统资源对这些线程进行管理。GCD的干活方法,使其拥有广大亮点(快、稳、准):

  • 急忙,更快之内存效率,因为线程栈不暂时存于应用内存。
  • 稳,提供了机关的和完美的线程池管理机制,稳定而方便。
  • 以,提供了直接以简单的调用接口,使用方便,准确。

  单例模式是同一栽时以的软件设计模式。在她的中心结构被才含一个叫称呼单例的超常规类。通过单例模式可保证系统中采用该模式的切近就发一个实例。即一个近乎才生一个实例

仲、队列和职责

初学GCD的时刻,肯定会纠结有近乎十分重点而却毫无意义的题目。比如:GCD和线程到底什么关系;异步任务到底以哪个线程工作;队列到底是单什么东西;mian
queue和main
thread到底为什么名堂等等。现在,这些我们一直略过(最后拾遗中会谈一下),苹果既然推荐应用GCD,那么为什么还要纠结于线程呢?需要关注之单纯出三三两两单概念:队列、任务。

定义:

1. 队列

调度班是一个目标,它会盖first-in、first-out的点子管理而提交的职责。GCD有三种队列类型:

  • 阴差阳错行队列,串行队列将任务为先进先出(FIFO)的逐条来推行,所以串行队列经常用来举行看一些特定资源的旅处理。你可为冲需要创造多单班,而这些队列相对其他队都是出新执行之。换句话说,如果你创造了4只串行队列,每一个序列在同一时间都单实行一个职责,对当下四个任务以来,他们是互独立且并作执行之。如果急需创造串行队列,一般用dispatch_queue_create这个措施来贯彻,并点名队列类型DISPATCH_QUEUE_SERIAL。
  • 彼此队列,并作班虽然是力所能及以推行多单任务,但这些任务依然是准事先到事先实施(FIFO)的逐一来实行之。并发队列会基于系统负荷来当地选择并发执行这些任务。并发队列一般指的便是全局队列(Global
    queue),进程中设有四只全局队列:高、中(默认)、低、后台四个优先级列,可以调用dispatch_get_global_queue函数传入优先级来做客队列。当然我们呢可就此dispatch_queue_create,并点名队列类型DISPATCH_QUEUE_CONCURRENT,来好创建一个涌出队列。
  • 预示队列,与主线程功能相同。实际上,提交至main
    queue的任务会于主线程遭遇实行。main
    queue可以调用dispatch_get_main_queue()来收获。因为main
    queue是同主线程相关的,所以这是一个串行队列。和其它串行队列一样,这个班中之天职一样潮只能实行一个。它会担保有的职责都以主线程执行,而主线程是唯一可用以创新
    UI 的线程。

外加说一样句子,上面吧说了,队列中的行是互为的,但是也存在部分限制。比如,并行执行的行数量被内核数的限制,无法真正好大量列并行执行;比如,对于彼此队列中之大局队列而言,其存优先级关系,执行之时光吗会以其先顺序,而非是并行。

  一个近似有还只有发一个实例,并且自动实例化向所有系统提供。

2. 任务

linux内核中之天职之概念是描述进程的一致栽结构体,而GCD中之职责就是一个代码块,它好靠一个block或者函数指针。根据这代码块上加进去队列的点子,将任务分为同步任务以及异步任务:

  • 一齐任务,使用dispatch_sync将任务在队列。将联合任务在串行队列,会相继执行,一般不这么做而以一个职责不竣工时调整起其它并任务会死锁。将同任务在并行队列,会挨个执行,但是呢没什么意义。
  • 异步任务,使用dispatch_async将任务在队列。将异步任务在串行队列,会挨个执行,并且不见面并发死锁问题。将异步任务在并行队列,会并行执行多只任务,这也是咱们绝常用之同一种植方式。

特点:

3. 简便用

// 队列的创建,queue1:中(默认)优先级的全局并行队列、queue2:主队列、queue3:未指定type则为串行队列、queue4:指定串行队列、queue5:指定并行队列
dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queue2 = dispatch_get_main_queue();
dispatch_queue_t queue3 = dispatch_queue_create("queue3", NULL);
dispatch_queue_t queue4 = dispatch_queue_create("queue4", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue5 = dispatch_queue_create("queue5", DISPATCH_QUEUE_CONCURRENT);

// 队列中添加异步任务
dispatch_async(queue1, ^{
// 任务
...
});

// 队列中添加同步任务
dispatch_sync(queue1, ^{
// 任务
...
});

       1、单例类只能有一个实例。

老三、GCD常见用法及利用场景

老喜欢同一句子话:Talk is cheap, show me the
code.接下来对GCD的使,我会通过代码展示。

  2、单例类必须协调创立和谐的绝无仅有实例。

1. dispatch_async

貌似用法

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
    // 一个异步的任务,例如网络请求,耗时的文件操作等等
    ...
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI刷新
        ...
    });
});

使用场景
这种用法非常大,比如被一个异步的网络要,待数额返回后返回主队列刷新UI;又随要图片,待图片返回刷新UI等等。

  3、单例类必须被拥有其他对象提供即时无异实例。

2. dispatch_after

一般用法

dispatch_queue_t queue= dispatch_get_main_queue();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), queue, ^{
    // 在queue里面延迟执行的一段代码
    ...
});

以场景
随即吗我们提供了一个简约的缓执行的办法,比如以view加载结束延迟执行一个动画片等等。

心想事成方式:

3. dispatch_once

相似用法

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // 只执行一次的任务
    ...
});

应用场景
好用其缔造一个单例,也足以做一些外只实行同一不行的代码,比如开一个不过能够接触同样糟糕的button(好像没啥用)。

  一般的话,我们出以下几独必要的操作:

4. dispatch_group

诚如用法

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^{
    // 异步任务1
});

dispatch_group_async(group, queue, ^{
    // 异步任务2
});

// 等待group中多个异步任务执行完毕,做一些事情,介绍两种方式

// 方式1(不好,会卡住当前线程)
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
...

// 方式2(比较好)
dispatch_group_notify(group, mainQueue, ^{
    // 任务完成后,在主队列中做一些操作
    ...
});

动场景
上述的同种方式,可以适用于自己维护的一些异步任务之一块儿问题;但是对早已封装好的部分库房,比如AFNetworking等,我们无取其异步任务的队,这里可以通过一样种计数的措施决定任务中共,下面为缓解单界面多接口的平等种植方法。

// 两个请求和参数为我项目里面的不用在意。

// 计数+1
dispatch_group_enter(group);
[JDApiService getActivityDetailWithActivityId:self.activityId Location:stockAddressId SuccessBlock:^(NSDictionary *userInfo) {
    // 数据返回后一些处理
    ...

    // 计数-1
    dispatch_group_leave(group);
} FailureBlock:^(NSError *error) {
    // 数据返回后一些处理
    ...

    // 计数-1
    dispatch_group_leave(group);
}];

// 计数+1
dispatch_group_enter(group);
[JDApiService getAllCommentWithActivityId:self.activityId PageSize:3 PageNum:self.commentCurrentPage SuccessBlock:^(NSDictionary *userInfo) {
    // 数据返回后一些处理
    ...

    // 计数-1
    dispatch_group_leave(group);
} FailureBlock:^(NSError *error) {
    // 数据返回后一些处理
    ...

    // 计数-1
    dispatch_group_leave(group);
}];

// 其实用计数的说法可能不太对,但是就这么理解吧。会在计数为0的时候执行dispatch_group_notify的任务。
dispatch_group_notify(group, mainQueue, ^{
    // 一般为回主队列刷新UI
    ...
});

    1、私有化构造方法;

5. dispatch_barrier_async

貌似用法

// dispatch_barrier_async的作用可以用一个词概括--承上启下,它保证此前的任务都先于自己执行,此后的任务也迟于自己执行。本例中,任务4会在任务1、2、3都执行完之后执行,而任务5、6会等待任务4执行完后执行。

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    // 任务1
    ...
});
dispatch_async(queue, ^{
    // 任务2
    ...
});
dispatch_async(queue, ^{
    // 任务3
    ...
});
dispatch_barrier_async(queue, ^{
    // 任务4
    ...
});
dispatch_async(queue, ^{
    // 任务5
    ...
});
dispatch_async(queue, ^{
    // 任务6
    ...
});

动场景
和dispatch_group类似,dispatch_barrier也是异步任务中的相同栽共同方式,可以于依照文件的读写操作时采用,保证读操作的准头。另外,有少数要注意,dispatch_barrier_sync和dispatch_barrier_async只当好创办的并发队排上中,在全局(Global)并作班、串行队列上,效果及dispatch_(a)sync效果同样。

    2、final类(定义为不可连续,这点开及从来不关联,暂时还当研讨)

6. dispatch_apply

诚如用法

// for循环做一些事情,输出0123456789
for (int i = 0; i < 10; i ++) {
    NSLog(@"%d", i);
}

// dispatch_apply替换(当且仅当处理顺序对处理结果无影响环境),输出顺序不定,比如1098673452
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/*! dispatch_apply函数说明
*
*  @brief  dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API
*         该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等到全部的处理执行结束
*
*  @param 10    指定重复次数  指定10次
*  @param queue 追加对象的Dispatch Queue
*  @param index 带有参数的Block, index的作用是为了按执行的顺序区分各个Block
*
*/
dispatch_apply(10, queue, ^(size_t index) {
    NSLog(@"%zu", index);
});

行使场景
那么,dispatch_apply有什么用也,因为dispatch_apply并行的运行机制,效率一般快于for循环的类串行机制(在for一浅巡回中的拍卖任务多时常别较特别)。比如就得为此来拉取网络数据后提前算出各个控件的高低,防止绘制时算,提高表单滑动流畅性,如果就此for循环,耗时比多,并且每个表单的数据尚未依赖关系,所以用dispatch_apply比较好。

    3、将看似的实例对象定义为一个私的习性(不限量也成员变量)

7. dispatch_suspend和dispatch_resume

一般用法

dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_suspend(queue); //暂停队列queue
dispatch_resume(queue);  //恢复队列queue

使用场景
这种用法自还尚无品味了,不过里面有个待注意的点。这半只函数不会见潜移默化到队中都推行的天职,队列暂停后,已经上加到行列中不过还不曾履行之天职不会见履行,直到队列被恢复。

    4、通过getInstance()方法取得实例,若私有的实例属性对象引用不呢空则返回,否则实例化该属性并返

8. dispatch_semaphore_signal

诚如用法

// dispatch_semaphore_signal有两类用法:a、解决同步问题;b、解决有限资源访问(资源为1,即互斥)问题。
// dispatch_semaphore_wait,若semaphore计数为0则等待,大于0则使其减1。
// dispatch_semaphore_signal使semaphore计数加1。

// a、同步问题:输出肯定为1、2、3。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore1 = dispatch_semaphore_create(1);
dispatch_semaphore_t semaphore2 = dispatch_semaphore_create(0);
dispatch_semaphore_t semaphore3 = dispatch_semaphore_create(0);

dispatch_async(queue, ^{
    // 任务1
    dispatch_semaphore_wait(semaphore1, DISPATCH_TIME_FOREVER);
    NSLog(@"1\n");
    dispatch_semaphore_signal(semaphore2);
    dispatch_semaphore_signal(semaphore1);
});

dispatch_async(queue, ^{
    // 任务2
    dispatch_semaphore_wait(semaphore2, DISPATCH_TIME_FOREVER);
    NSLog(@"2\n");
    dispatch_semaphore_signal(semaphore3);
    dispatch_semaphore_signal(semaphore2);
});

dispatch_async(queue, ^{
    // 任务3
    dispatch_semaphore_wait(semaphore3, DISPATCH_TIME_FOREVER);
    NSLog(@"3\n");
    dispatch_semaphore_signal(semaphore3);
});

// b、有限资源访问问题:for循环看似能创建100个异步任务,实质由于信号限制,最多创建10个异步任务。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
for (int i = 0; i < 100; i ++) {
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_async(queue, ^{
    // 任务
    ...
    dispatch_semaphore_signal(semaphore);
    });
}

运用场景
其实关于dispatch_semaphore_t,并没看到最多采用和资料说明,我只得参照自己对linux信号量的知情写了个别独用法,经测试确实相似。这里,就未针对一部分死锁问题开展讨论了。

  这里先介绍四种植实现方式

9. dispatch_set_context、dispatch_get_context和dispatch_set_finalizer_f

一般用法

// dispatch_set_context、dispatch_get_context是为了向队列中传递上下文context服务的。
// dispatch_set_finalizer_f相当于dispatch_object_t的析构函数。
// 因为context的数据不是foundation对象,所以arc不会自动回收,一般在dispatch_set_finalizer_f中手动回收,所以一般讲上述三个方法绑定使用。

- (void)test
{
    // 几种创建context的方式
    // a、用C语言的malloc创建context数据。
    // b、用C++的new创建类对象。
    // c、用Objective-C的对象,但是要用__bridge等关键字转为Core Foundation对象。

    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    if (queue) {
        // "123"即为传入的context
        dispatch_set_context(queue, "123");
        dispatch_set_finalizer_f(queue, &xigou);
    }
    dispatch_async(queue, ^{
        char *string = dispatch_get_context(queue);
        NSLog(@"%s", string);
    });
}

// 该函数会在dispatch_object_t销毁时调用。
void xigou(void *context)
{
    // 释放context的内存(对应上述abc)

    // a、CFRelease(context);
    // b、free(context);
    // c、delete context;
}

应用场景
dispatch_set_context可以吗队列添加上下文数据,但是因GCD是C语言接口形式的,所以该context参数类型是“void
*”。需利用上述abc三种办法开创context,并且一般做dispatch_set_finalizer_f使用,回收context内存。

      1、饿汉模式

季、内存和安全

稍稍提一下吧,因为一些人数纠结于dispatch的内存问题。
内存

  • MRC:用dispatch_retain和dispatch_release管理dispatch_object_t内存。
  • ARC:ARC在编译时刻自动管理dispatch_object_t内存,使用retain和release会报错。

安全
dispatch_queue是线程安全之,你得随心所欲往里长任务。

    2、懒汉模式

五、拾遗

这里要提一下GCD的部分坑和线程的有些问题。

    3、双重认证

1. 死锁

dispatch_sync

// 假设这段代码执行于主队列
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t mainQueue = dispatch_get_main_queue();

// 在主队列添加同步任务
dispatch_sync(mainQueue, ^{
    // 任务
    ...
});

// 在串行队列添加同步任务 
dispatch_sync(serialQueue, ^{
    // 任务
    ...
    dispatch_sync(serialQueue, ^{
        // 任务
        ...
    });
};

dispatch_apply

// 因为dispatch_apply会卡住当前线程,内部的dispatch_apply会等待外部,外部的等待内部,所以死锁。
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(10, queue, ^(size_t) {
    // 任务
    ...
    dispatch_apply(10, queue, ^(size_t) {
        // 任务
        ...
    });
});

dispatch_barrier
dispatch_barrier_sync在串行队列和全局并行队列中跟dispatch_sync同样的成效,所以用考虑同dispatch_sync一样的死锁问题。

    4、静态内部类模式

2. dispatch_time_t

// dispatch_time_t一般在dispatch_after和dispatch_group_wait等方法里作为参数使用。这里最需要注意的是一些宏的含义。
// NSEC_PER_SEC,每秒有多少纳秒。
// USEC_PER_SEC,每秒有多少毫秒。
// NSEC_PER_USEC,每毫秒有多少纳秒。
// DISPATCH_TIME_NOW 从现在开始
// DISPATCH_TIME_FOREVE 永久

// time为1s的写法
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);

 

3. GCD和线程的涉

假设你是新手,GCD和线程暂时木有关系。
假使你是高手,我们召开朋友吧。

事先看率先种方法,饿汉模式顾名思义,迫不及待的感怀要吃(初始化实例),在类似吃定义一个私房静态本类的实例化对象,在近似加载的过程就是进行这目标的实例化,之后的对此类实例的调用都是调整用者实例。

六、参考文献

1、https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html\#//apple\_ref/doc/uid/TP40008091-CH102-SW2
2、https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD\_libdispatch\_Ref/
3、http://tutuge.me/2015/04/03/something-about-gcd/
4、http://www.jianshu.com/p/85b75c7a6286
5、http://www.jianshu.com/p/d56064507fb8

代码如下:

public class Singleton2 {

    private static Singleton2 singleton2= new Singleton2();

    private Singleton2(){}

    public static Singleton2 getInstance() {
        return singleton2;
    }

    public static String getStr() {
        return "Create String type Object";
    }
}

饿汉模式是较为简单的兑现方式,同样为是比较常用的法子。但他具有一定之症结:虽然在单例模式被大多都只调用getInstance()方法,但切莫脱来另的主意导致类似加载,比如使类似中getStr()这种与类似的实例无关之方而叫调用,就会触发类加载,从而对静态成员开展初始化,但是此类有或并不需要实例化,这样于某种程度上会见导致一定之资源浪费。也不怕无法上lazy loading的效益。

 

即就是引入了懒汉模式

 

懒汉模式:只有在首先这个调用类的实例对象时才见面初始化类的实例,从而实现延迟加载

代码如下

public class Singleton3 {

    private static Singleton3 singleton2 = null;

    private Singleton3(){
        Tools.println("类实例化");
    }

    public static synchronized Singleton3 getInstance(){
        if(singleton2 == null)
            singleton2 = new Singleton3();
        return singleton2;
    }

    public static void CreateString(){
        Tools.print("Create String in Singleton3");
    }
}

懒汉模式通过getInstance()方法创建实例,这样只有以使到实例的当儿才见面初始化实例对象,实现了延加载,但是这种模式会并发线程同步问题:一个线程调用了getInstace()方法,判断为空后展开实例的始建,此时还要生出矣一个线程调用了getInstance()方法,但这时首先单线程还没有完实例化的操作,故此线程也会见实例化一个靶。所以我们得也getInstance()方法加上一道关键字synchronized

那么问题来了,我们运用延缓加载就是为着提升系统特性,而引入了旅关键字则会大大影响多线程情况下之性,所以是方式也闹立万分可怜的毛病。

 

下面就引入了重新检测方法

 

更检测方法:通过再检测的法子成功延迟加载

代码如下:

class Singleton1 {

    private Singleton1() {
    }

    public static Singleton1 instance = null;

    public static Singleton1 getInstance() {
        if (instance == null) {
            synchronized (Singleton1.class) {
                if (instance == null) {
                    instance = new Singleton1();
                }
            }
        }
        return instance;
    }
}

可看看,首先判断实例对象是否也空,如果判断通过再进行共同操作。

这种措施是缓解了懒汉模式之频率问题,但还要为有有题目,第一不成加载时反应不快,由于java内存模型一些因偶尔失败。失败原因可以详细http://blog.csdn.net/chenchaofuck1/article/details/51702129

 

接通下引入一栽就比较完美同时使用比较多之一模一样种实现方式:静态内部类实现

代码如下:管理

public class Singleton4 {

private Singleton4(){}

static class SingletonHolder {

private static Singleton4 singleton = new Singleton4();

}

public static Singleton4 getInstance(){

return SingletonHolder.singleton;

}

}

夫方式利用了:静态内部类并无见面于外表类类加载的上吧开展类似加载,而是以其本身第一不善吃采取时进行类似加载,并且jvm的类加载过程是指向线程非常融洽之,所以我们不欲担心联合问题。

public class Singleton4 {

    private Singleton4(){}

    static class SingletonHolder {
        private static Singleton4 singleton = new Singleton4();
    }

    public static Singleton4 getInstance(){
        return SingletonHolder.singleton;
    }
}

 

上述方法还是差不多实现了单例模式,但是仍时有发生半点独问题亟需小心:

1:如果单例由不同之类装载器注入,那边有或有来多个单例类的实例。假如不是远端存取,假如有些servlet容器对每个servlet使用不同之类装载器,他们便见面生出只字的单例类的实例。

2:如果单例类实现了java.io.Serializable接口,那么此类的实例就好为序列化和回复,如果序列化一个靶,然后还原多单是目标,就见面并发多只单例类的实例。

至于此题材可参考者篇:http://blog.csdn.net/fg2006/article/details/6409423

 

先是个问题的化解方式:

private static Class getClass(String classname)      
                                         throws ClassNotFoundException {     
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();     

      if(classLoader == null)     
         classLoader = Singleton.class.getClassLoader();     

      return (classLoader.loadClass(classname));     
   }     
}

老二只问题之缓解办法:

public class Singleton implements java.io.Serializable {     
   public static Singleton INSTANCE = new Singleton();     

   protected Singleton() {     

   }     
   private Object readResolve() {     
            return INSTANCE;     
      }    
}  

 

就有限种方式是自个儿自从任何的博客上看来的,现在尚于询问中。。。

 

 

用场景:

  1. Windows的Task
    Manager(任务管理器)就是坏独立的单例模式(这个特别熟稔吧),想想看,是不是吧,你能够开拓两只windows
    task manager吗? 不信教你协调摸索看哦~ 

  2. windows的Recycle
    Bin(回收站)也是首屈一指的单例应用。在全方位系统运行过程中,回收站一直维护着才局部一个实例。

  3. 网站的计数器,一般也是采取单例模式实现,否则难以同。

4.
应用程序的日记应用,一般都何用单例模式实现,这相似是由共享的日记文件一直处在打开状态,因为只能发出一个实例去操作,否则内容不好搭。

5.
Web应用之布对象的读取,一般为使用单例模式,这个是由配备文件是共享的资源。

6. 数据库连接池的设计一般为是利用单例模式,因为数据库连接是均等种数据库资源。数据库软件系统被运用数据库连接池,主要是节省打开或者关闭数据库连接所引的频率损耗,这种频率及之吃还是十分贵之,因为何用单例模式来保护,就可大大降低这种损耗。

7.
大抵线程的线程池的计划一般也是采取单例模式,这是由线程池要方便对池中之线程进行控制。

8.
操作系统的文件系统,也是老的单例模式实现的有血有肉事例,一个操作系统只能有一个文件系统。

9. HttpApplication
也是单位例的出众以。熟悉ASP.Net(IIS)的全体请求生命周期的人口当懂得HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.

 

小结以上,不难看出:

  单例模式采用的景一般发现在偏下原则下:

  (1)资源共享的事态下,避免由于资源操作时造成的性还是吃等。如上述被的日志文件,应用配置。

  (2)控制资源的场面下,方便资源间的互动通信。如丝程池等。

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注