事件监听的统计时在线人数案例

一、iOS多线程

logout.jsp

GCD执行措施吧分为异步执行和共执行:
  • dispatch_async(异步执行)
    :不管队列中之职责履行完毕要没执行完毕,直接将任务多至队
  • dispatch_sync(同步执行) :
    等行列中的天职执行完毕,再用任务加至队

图片 1

实例:
NSThread *thread = threads[i];
//判断线程是否完成,如果没有完成则设置为取消状态
//注意设置为取消状态仅仅是改变了线程状态而言,并不能立刻终止线程
if ( !thread.isFinished ) {
    [thread cancel];
}
//线程休眠2秒
[NSThread sleepForTimeInterval:2.0];

咱清楚了决定单个线程,怎么当线程之间开展通信为?

图片 2

GCD的旁职责履行方式:
/* 重复执行某个任务,为了不阻塞线程可以使用dispatch_async()包装一下再执行 */
dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));

/* 单次执行一个任务,此方法中的任务只会执行一次,重复调用也没办法重复执行(单例模式中常用此方法)*/
dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);

/* 常用:延迟delayInSeconds秒后在队列queue执行block操作 */
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_queue_t queue, dispatch_block_t block);

图片 3

NSOperation是单基类,我们直接行使的是她的子类:
  • NSInvocationOperation:调用方法SEL的艺术实施线程可以用它们
  • NSBlockOperation:调用Block的方式实行线程可以使她

 图片 4

实质上行使:
/* 创建一个线程,初始化任务,创建线程并不会启动线程 */
NSThread *thread = [[NSThread alloc] initWithTarget:self 
                                           selector:@selector(loadImage) 
                                             object:nil];
[thread start];//启动线程

/* 直接将操作添加到新线程并启动线程 */
[NSThread detachNewThreadSelector:@selector(loadImage) 
                         toTarget:self 
                       withObject:nil];
  • 每个线程的骨子里施行各个并不一定按启动顺序执行
  • 设若是单核CPU,多线程是起,分时间片切换执行不同线程,多核CPU的多线程才是真正的互动运算。

 

线程状态分为:
  • isExecuting(正在实践)
  • isFinished(已经到位)
  • isCancellled(已经撤回)
 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 <html>
 3   <head>
 4     <title>$Title$</title>
 5   </head>
 6   <body>
 7     <h3>
 8       当前在线人数为:<%=application.getAttribute("count")%>
 9     </h3>
10     <a href="<%=response.encodeURL ("logout.jsp")%>">退出系统</a>
11   </body>
12 </html>
大多图加载实例:
- (void)loadImageWithMultiThread{
    int count = ROW_COUNT*COLUMN_COUNT;
    //创建线程队列
    NSOperationQueue *operationQueue = [[NSOperationQueue alloc]init];
    operationQueue.maxConcurrentOperationCount = 5;//设置最大并发线程数
    //创建加载最后一张图片的线程
    NSBlockOperation *lastBlockOperation = [NSBlockOperation blockOperationWithBlock:^{
        [self loadImage:[NSNumber numberWithInt:(count-1)]];
    }];
    //创建多个线程用于下载其他图片
    for (int i=0; i<count-1; ++i) {
        //创建多线程操作
        NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
            [self loadImage:[NSNumber numberWithInt:i]];
        }];
        //设置依赖操作为最后一张图片加载操作,只有最后一张图片加载完成,其他图片才开始陆续加载
        [blockOperation addDependency:lastBlockOperation];
        [operationQueue addOperation:blockOperation];
    }
    //将最后一个图片的加载线程加入线程队列
    [operationQueue addOperation:lastBlockOperation];
}

靠的利用-多图加载-最后一个图形先加载,其他才起加载

 

队的异步执行及共同实施:
//异步执行队列任务,第一个参数是队列,第二个参数是任务Block
dispatch_async(queue, ^{
    [self loadImage:[NSNumber numberWithInt:i]];
}); 
//同步执行队列任务,第一个参数是队列,第二个参数是任务Block
dispatch_sync(queue, ^{
    [self loadImage:[NSNumber numberWithInt:i]];
}); 
  • 在GDC中一个操作是多线程执行要单线程执行,取决于当前班类型以及行方式,只有队列类型也互相队列并且动用异步方法实施时才会于多独线程中连作执行
  • 串行列可以按照依次执行,并行队排的异步方法无法确定实施顺序。
  • 更新UI界面最为好以共方法,其他操作使用异步方法。
 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 <html>
 3 <head>
 4     <title>Title</title>
 5 </head>
 6 <body>
 7   <%session.invalidate();%>
 8     <h3>您已退出系统</h3>
 9 </body>
10 </html>

四、GCD

GCD中呢生一个接近于NSOperationQueue的排,GCD统一管理全队列中之职责,GCD是C语言下的框架。

图片 5

三、NSOperation

假如用NSOperation放入NSOperationQueue线程队列中,就见面启动推行。
NSOperationQueue负责管理、执行有的NSOperation,这样更便于管制线程总数决定线程之间的依靠

 

若是您嗜自之稿子,请关注我O(∩_∩)O哈~

index.jsp

GCD中之阵分为并执行队列和串行队列:
  • 拧行队列(serial):只有一个线程,加入到行列中的操作以添加顺序依次执行。
  • 并作班(concurrent):有多单线程,操作上后她会用这些队列安排在可用的处理器上,同时确保先进来之任务优先处理,但非是逐一的。

实则当GCD中还有一个特种班就是主队列,用来实施主线程上的操作任务。

 1 import javax.servlet.ServletContext;
 2 import javax.servlet.ServletContextEvent;
 3 import javax.servlet.ServletContextListener;
 4 import javax.servlet.annotation.WebListener;
 5 import javax.servlet.http.HttpSessionAttributeListener;
 6 import javax.servlet.http.HttpSessionEvent;
 7 import javax.servlet.http.HttpSessionListener;
 8 import javax.servlet.http.HttpSessionBindingEvent;
 9 
10 @WebListener()
11 public class CountListener implements HttpSessionListener {
12     private int count=0;
13     public void  sessionCreated(HttpSessionEvent hse) {
14         count++;
15         ServletContext context = hse.getSession ().getServletContext ();
16         context.setAttribute ("count",new Integer (count));
17     }
18 
19     @Override
20     public void sessionDestroyed(HttpSessionEvent hse) {
21         count--;
22         ServletContext context = hse.getSession ().getServletContext ();
23         context.setAttribute ("count",new Integer (count));
24     }
25 }
脚是线程间通信的常用方法:
/* 在后台执行一个操作,本质就是重新创建一个线程执行当前方法 */
- (void)performSelectorInBackground:(SEL)aSelector
                         withObject:(id)arg;
/* 在指定的线程上执行一个方法,需要用户创建一个线程对象 */
- (void)performSelector:(SEL)aSelector
               onThread:(NSThread *)thr
             withObject:(id)arg
          waitUntilDone:(BOOL)wait;
/* 在主线程上执行一个方法 */
- (void)performSelectorOnMainThread:(SEL)aSelector
                         withObject:(id)arg
                      waitUntilDone:(BOOL)wait;

运不同之浏览器访问,防止公用一个session对象 

1.NSLock同步锁

//初始化锁对象
NSLock *myLock = [[NSLock alloc] init];
//加锁
[myLock lock];//加锁后,下面的代码只能有一个线程进入执行
if (_imageNames.count > 0) {
    name = [_imageNames lastObject];
    [_imageNames removeObject:name];
}
//使用完解锁
[myLock unlock];

五、线程同步

干什么要线程同步?因为一旦化解多线程的资源掠夺的问题

下是动实例:
//创建Invocation线程
NSInvocationOperation *invocationOperation = 
        [[NSInvocationOperation alloc] initWithTarget:self 
                                             selector:@selector(loadImage) 
                                               object:nil];
//注意如果直接调用start方法,则此操作会在主线程中调用
// [invocationOperation start];//一般不会这么操作,而是添加到NSOperationQueue中
//创建线程队列
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 5;//设置最大并发线程数
//注意添加到线程队列后,队列里的线程就会开始执行
[operationQueue addOperation:invocationOperation];

//创建Block线程
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
    [self loadImage:[NSNumber numberWithInt:0]];
}];
//添加进线程队列
[operationQueue addOperation:blockOperation];

倘当添加NSBlockOperation线程麻烦,还发生只大概的章程,是NSOperationQueue的对象方法:

// 快捷添加NSBlockOperation
[operationQueue addOperationWithBlock:^{
    [self loadImage:[NSNumber numberWithInt:0]];
}];

自身说了NSOperationQueue可以控制线程之间的仗,这是怎一转头事为?想象一种植现象,加载多独图片,但我想最后一摆放图纸一定要优先加载,其他图片加载的前提就是是最终一摆设图片要加载成功,这时候就得利用依赖了。非常简单。

iOS多线程开发出三种方法:
  1. NSThread
  1. NSOperation
  2. GCD

iOS在每个过程启动后都见面创造一个主线程更新UI要在主线程上,所以呢叫UI线程,是任何线程的父线程。

线程和经过的分傻傻分不清楚:
  • 线程(thread):用于代替独立执行之代码段。
  • 过程(process):用于代替一个正运行的可执行程序,它好涵盖多独线程。

差不多线程加载图片

出错行队列和并发队排的缔造:
/*创建一个队列
 第一个参数:队列名称
 第二个参数:队列类型,DISPATCH_QUEUE_SERIAL串行,DISPATCH_QUEUE_CONCURRENT并发
 注意:GCD的queue不是指针类型
*/
dispatch_queue_t serialQueue = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t concurrentQueue = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);

/* 使用dispatch_get_global_queue() 方法取得一个全局的并发队列 */
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

二、NSThread

NSThreadhi轻量级的多线程开发,需要团结管理线程生命周期

创建线程主要实现方式:
/* 直接将操作添加到新线程中并执行,该方法无法拿到线程对象 */
+ (void)detachNewThreadSelector:(SEL)selector /* 方法名 */
                       toTarget:(id)target /* 调用对象 */
                     withObject:(id)argument; /* 参数 */
/* 创建线程对象,初始化线程任务,调用start方法启动线程 */
- (instancetype)initWithTarget:(id)target /* 调用对象 */
                      selector:(SEL)selector /* 方法名 */
                        object:(id)argument;/* 参数 */
脚是常用方法来控制线程:
/* 让线程休眠 */
+ (void)sleepUntilDate:(NSDate *)date;/* 让当前执行线程休眠到某个时间 */
+ (void)sleepForTimeInterval:(NSTimeInterval)time;/* 让当前执行线程休眠固定多少秒 */
/* 终止线程 */
+ (void)exit;
/* 停止线程,注意在主线程中调用仅仅只是设置线程状态,不会立刻停止线程 */
- (void)cancel;

2.@synchronized代码块

//线程同步
@synchronized(self){
    if (_imageNames.count > 0) {
        name = [_imageNames lastObject];
        [_imageNames removeObject:name];
    }
}

线程同步就无密切讲了,这是一个大块知识。