如何编写多线程应用

现在你已经知道一个好的多线程应用是怎样的,它是如何帮助你解决问题的,那么如何编写一个好的多线程应用呢?我会向你介绍iPhone应用中编写和处理多线程应用的主要技术。

创建一个线程

为了创建一个线程,你可以使用下面的方法:

  • NSThread

  • POSIX Threads

  • NSObject 来创建一个新的线程

  • NSOperation和NSOperationQueue

我会逐一介绍他们,然后会举一些例子,因为他们都有各自的优点和缺点。在本部分结束的时候,我会给出一个表格来进行对比,是得你能够分清他们的不同,这样在你的需求中就能够选择一个正确的方案。

NSThread

用NSThread创建一个新的线程,你可以简单的调用:

[NSThread detachNewThreadSelector:@selector(threadMethod:) toTarget:self

withObject:nil];

这个方法会在你的应用中创建一个新的detached线程。一个detached线程就是它的所有资源会被系统回收,当线程存在的时候。

有些属性你需要知道。

+(void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

  • aSelector:当线程开始的时候,这个方法会在目标对象中被调用。根据苹果的文档,这个selector只有一个参数,没有返回值。

  • aTarget:将要执行在aSelector参数中所指定的方法的对象。

  • anArgument:唯一的一个参数;当线程开始的时候,它会被传递到aSelector方法中。

如果你想创建一个线程,但是不想启动它,你可以使用下面的机制:

  1. NSThread* myThread = [[NSThread alloc]initWithTarget:self

    selector:@selector(myThreadMainMethod:)object:nil];

    [myThread start]; // Actually create the thread

你可以看到,第一行,你创建了一个新的线程,然后,根据你的选择,你可以在对象上调用start来启动一个新的线程。这是非常有用的,如果你只想传递myThread对象,而不想传递selector,target和argument的话。

另一个比较好的做法是,使用NSThread对象发送一个消息给线程对象

  1. -(void)performSelector:(SEL)aSelector onThread:(NSThread *)thrwithObject:(id)arg waitUntilDone:(BOOL)wait

这个方法会在另一个线程上queue selector。当系统自动运行线程时,线程会dequeue这个消息,然后会调用aSelector变量指定的方法。

使用POSIX线程

这个在iPhone应用中主要是用c编程时会用到。在第9章,我会更深入的讨论c编程,并能够帮助你在很多情况下提升你的iPhone apps的性能。所以这个部分可能不会帮助你太多,如果你还不了解c编程的话。如果你已经了解了c编程,Listing 6-3 展示了代码,后面会有一个解释。

Listing 6–3. POSIX Thread#include <assert.h>

#include <pthread.h>

void* ThreadMethod(void* data){

// Your main logic comes here.

return NULL;

}

void LaunchThread(){

// Create the thread using POSIX routines.

pthread_attr_t attr;
       pthread_t posixThreadID;
       int returnVal;

// init and check if init a new thread successful

returnVal =  pthread_attr_init(&attr);

assert(!returnVal);

// set attribute detach state for new thread
       returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

assert(!returnVal);

// create and run the new thread
       int threadError = pthread_create(&posixThreadID, &attr, &ThreadMethod, NULL);

returnVal = pthread_attr_destroy(&attr);

assert(!returnVal);
       if (threadError != 0)
       {

// Report an error.

}

}

NSObject

所有的对象都可以创建和detach一个新的线程来执行这些对象的selectors。你可以使用下面的这行代码在后台线程中运行doSomething方法:

[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];

调用这个方法的效果和下面的这行代码是一样的:

[NSThread detachNewThreadSelector:@selector(doSomething) toTarget:myObj withObject:nil]

这个方法是比较好的,对于detach和创建一个运行后台任务的线程来说。

NSOperationQueue

NSOperationQueue是管理和运行并发任务的一个机制。NSOperationQueue的一个好处是它能够限制系统内部并发operations的数量,通过给定一个限制使得系统加载在一个可以接受的范围水平。因为这个最大线程数量的限制,如果有更多的线程实例,NSOperationQueue不会导致更多的并发线程同时在系统中运行。

你可以在queue中添加operations,但是不能删除。然而,你可以在queue中取消所有已经存在的和还没有运行的operations。表格 6-2 展示了当使用NSOperationQueue时,一些非常有用的方法。

你可以用3个不同的类来使用NSOperationQueue。

  • NSInvocationOperation:如果你已经有一个对象和一个方法加入到一个并发线程中,这只是一个简单的包裹。它不需要子类,所以通过这个类来创建一个简单的NSOperation对象。NSInvocationOperation是NSOperation的子类。

  • NSBlockOperation:这是另一包裹类,用来执行一个或多个blocks,而不需要创建一个单独的NSOperation对象来执行每一个block。当执行超过一个block时,只有所有内部的blocks都执行完毕,那么NSBlockOperation才被认为结束了。

  • Custom NSOperation:NSOperation是一个基类。通过继承它,你能够完全的控制整个NSOperation对象的实现,包括你的operation执行说的默认行为和报告它的状态。

使用NSOperationQueue进行多线程设计,你需要用这3个方法中的一个来创建指定的对象,然后把新创建的NSOperation加入到你的queue中。然后这个queue会为你维护和运行这些operations。

这里有一个简单的代码来帮助你创建一个NSOperationQueue,然后把相互独立的operation对象放进去,来创建一个多线程环境:

  1. NSOperationQueue* myOperationQueue = [[NSOperationQueue alloc] init];
    [myOperationQueue addOperation:myOperation]; // Add a single operation
    [myOperationQueue addOperations:arrayOfOperations waitUntilFinished:NO]; // Add multipleoperations
    [aQueue addOperationWithBlock:^{

    /* Do Something. */

  2. }];

转载于:https://blog.51cto.com/ikinglai/1259292

iOS使用多线程提高数据并发访问 之三相关推荐

  1. iOS使用多线程提高数据并发访问 之七

    活跃性 活跃性是指好的事情最终会发生.例如,如果你代码的目标是确保你能够持续从数组中push和pop对象,问题是这个过程是否能够永远工作.使用锁带来的问题是锁会引起系统中所有线程一直等待 -- 换句话 ...

  2. Entity Framework 数据并发访问错误原因分析与系统架构优化

    本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上线后,使用频率较高,故在实际使用和后期的问题重现测试中,产生了一下系 ...

  3. 多线程与高并发基础一(超发--多线程悲观锁,乐观锁、类数据库悲观锁乐观锁)

    PS:看完文章后对自己以前所做过的并发和锁机制有了深入原理的了解. 知其然和知其所以然! 遂以记之! 关键词: 线程,同步,单例,高并发,高访问,死锁 一.大规模并发带来的挑战 在过去的工作中,我曾经 ...

  4. python paramiko并发_使用Python paramiko模块利用多线程实现ssh并发执行操作

    1.paramiko概述 ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography). 有了Paramiko以 ...

  5. 提高大数据量并发访问时效率

    最近在做windows服务方面的开发,主要用它来解决A服务和其他服务发送数据失败后,重新发送的问题. 为了提高大数据量并发访问时效率问题,要在多台服务器上安装服务并采用多线程,就像是超市的收银,利用多 ...

  6. ios并发会造成什么问题_iOS Core data多线程并发访问的问题

    大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的 ...

  7. 多线程中数据的并发访问与保护

    在多线程编程中,不可避免地要对一些共享的数据进行访问.由于线程之间对共享数据的访问是独立的,任何一个线程都可对共享数据进行访问和修改,且它们之间是异步并发进行的,特别是当需要对共享数据进行修改时,就会 ...

  8. 如何提高服务器响应的数据速度_如何提高服务器并发处理能力

    作者:潇洒一剑 来源:cnblogs.com/zengjin93/p/5569556.html 说明 以下内容为入门级介绍,意在对老技术作较全的总结而不是较深的研究.主要参考<构建高性能Web站 ...

  9. 大数据量高并发访问的数据库优化方法

    一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...

  10. EF Core下利用Mysql进行数据存储在并发访问下的数据同步问题

    小故事 在开始讲这篇文章之前,我们来说一个小故事,纯素虚构(真实的存钱逻辑并非如此) 小刘发工资后,赶忙拿着现金去银行,准备把钱存起来,而与此同时,小刘的老婆刘嫂知道小刘的品性,知道他发工资的日子,也 ...

最新文章

  1. linux上安装mysql,tomcat,jdk
  2. 数据库基础-数据库引擎
  3. 深度学习4:使用MNIST数据集(tensorflow)
  4. linux yum localinstall 解决本地rpm包的依赖问题
  5. Eclipse中server启动超时的解决方法
  6. Makefile中的变量和shell变量
  7. UVA11212Editing aBook 编辑书稿
  8. Nova Suspend/Rescue 操作详解 - 每天5分钟玩转 OpenStack(35)
  9. VS2008源代码管理软件组合-visualSVN Server+TortoiseSVN+AnkhSvn
  10. (转)Locale 详解
  11. [收藏]深入浅出的《网络socket编程指南》4
  12. 算法题目打卡:Ques20201007
  13. Exp3 免杀原理与实践 20154328 常城
  14. 2012电商倒闭潮——死亡的电商整理
  15. 微信戴圣诞帽的一个简易实现程序
  16. python xpath定位 麦客表单
  17. qt 批量裁剪图片_照片变素描,不用下载App,好用的在线图片处理及图库
  18. grabber的使用_Google Grabber —使用PHP找出您的域名在Google中列出了多少页
  19. Chrome浏览器各种崩溃、卡死解决方法
  20. Java通信之服务器生猛上手

热门文章

  1. 深度学习:概述和一孔之见 浅谈深度学习中潜藏的稀疏表达
  2. Python集合set与frozenset的区别
  3. 【Nowcoder - 5670 B Graph】2020 牛客暑期多校训练营(第五场)【最小异或生成树、Boruvka 思想】
  4. 使用SecretScanner发现容器镜像和文件系统中的敏感数据
  5. android xml红心圆,Android自定义View圆形图片控件代码详解
  6. linux虚拟机安装samba服务,在虚拟机Redhat Linux下安装Samba服务器分享
  7. sql常识- UNIQUE
  8. iOS开发——源代码管理——git(分布式版本控制和集中式版本控制对比,git和SVN对比,git常用指令,搭建GitHub远程仓库,搭建oschina远程仓库 )...
  9. mysql 开启用户远程登录
  10. C语言中结构体赋值问题的讨论