多线程通识

1. 了解多线程的思维

线程是用来执行任务的,线程彻底执行完任务A才能去执行任务B。为了同时执行两个任务,产生了多线程。

例子:

我打开一个视频软件,我开辟一个线程A让它执行下载任务,我开辟一个线程B,用来播放视频。我开辟两个线程后,这两个任务能同时执行,如果我开辟一个线程,只有下载任务完成,才能去执行播放任务。

线程相当于店里的服务员,一个服务员同时只能做一件事情,多顾几个服务员,就能同时做很多事情。

2. 进程(学习线程之前,必须要了解一下进程)

1. 进程就是在操作系统中运行的程序。专业点说,进程是应用程序的执行实例

2. 进程不能执行任务

3. 进程在运行时创建的资源随着进程的终止而死亡

3. 线程

1. 进程本身是不能执行任务的,进程想要执行任务必须的有线程,线程是进程内部的一个独立的执行单元,同时只能执行一个任务。线程被分为两种。主线程(用户界面线程)和子线程(工作线程或后台线程)。我在望京(操作系统)开了一个橘子产品体验店(进程),里面有很多工作人员,有店长帮我布置门面(主线程),咨询人员(子线程)、销售人员(子线程)。

2. 线程执行完毕就会被销毁

3. 主线程:当应用程序启动时自动创建和启动,通常用来处理用户的输入并响应各种事件和消息,主线程的终止也意味着该程序的结束。

4. 子线程:由主线程来创建,用来帮助主线程执行程序的后台处理任务。如果子线程A中有创建了一个子线程B,在创建之后,这两者就会是相互独立的,多个子线程之间效果上可以同时执行。

5. 一个进程可以有多个线程,并且所有线程都在该进程的虚拟地址空间中,可以使用进程的全局变量和系统资源。

6. 线程的五种状态:http://blog.csdn.net/peter_teng/article/details/10197785

4. 多线程

1. 目前大多数的app,都需要连接服务器,而访问服务器的速度可能快也可能很慢。如果一个app访问服务器的操作没有在子线程操作的话,在该app访问服务器的过程中,该软件是不能响应用户的操作的,只有该app访问结束以后,app才能响应用户的操作,这就造成线程阻塞,也就是我们常见的卡顿现象。一条线程在同一时间内只能执行一个任务,但是进程可以有多条线程。可以开启多条线程来执行不同的任务,从而提高程序的执行效率,避免线程阻塞。

2. 每个线程都可以设置优先级,操作系统会根据线程的优先级来安排CPU的时间,优先级高的线程,优先调用的几率会更大,同级的话,执行的先后对线程执行的先后有影响

3. 同一时间内,CPU只能处理一条线程,只有一条线程在工作。多线程并行执行,其实就是各个线程不断切换,因为执行切换的时间很快很快,就造成了同时执行的假象,原理如下,比如A,B两个线程;

1.A执行到某一时间段要切换了,可A任务没完成,系统就会把A当前执行的位置和数据以入栈的方式保存起来

2.然后B线程执行,B执行时间到了,它的位置状态等也会被系统保存到B的栈中。

3.系统自动找到A的栈,将A之前保存的数据恢复,又可以从A之前断开的状态继续执行下去,如此循环

4. 系统每开一个线程都有比较大的开销,若线程开的过多,不仅会占用大量内存和让城乡变得更加复杂,而且会加重CPU的负担,这样的软件,会让你省掉冬天买暖手宝的钱。

5. 多线程的优势

1. 提高程序执行效率,避免线程阻塞造成的卡顿现象
2. 能适当提高资源利用率(CPU,内存)

6. 多线程的不足

1. 开启线程需要占用一定的内存空间
2. 线程越多,CPU在线程调度上的开销就越大
3. 程序设计更加复杂:比如线程之间的通信、多线程的数据共享

5. 总结

1. 线程与进程的关系

1. 线程是CPU执行任务的基本单位,一个进程能有多个线程,但同时只能执行一个任务
2. 进程就是运行中的软件,是动态的
3. 一个操作系统可以对应多个进程,一个进程可以有多条线程,但至少有一个线程
4. 同一个进程内的线程共享进程里的资源

2. 主线程

1. 进程一启动就自动创建
2. 显示和刷新UI界面
3. 处理UI事件

3. 子线程

1. 处理耗时的操作
2. 子线程不能用来刷新UI

实例:多个UIImageView加载图片

//

//  MoreImageViewController.m

//  NSThread

//

//  Created by Biaoac on 16/3/2.

//  Copyright © 2016年 scsys. All rights reserved.

//

#import "MoreImageViewController.h"

#define kURRl @"http://store.storeimages.cdn-apple.com/8748/as-images.apple.com/is/image/AppleInc/aos/published/images/s/38/s38ga/rdgd/s38ga-rdgd-sel-201601?wid=848&hei=848&fmt=jpeg&qlt=80&op_sharpen=0&resMode=bicub&op_usm=0.5,0.5,0,0&iccEmbed=0&layer=comp&.v=1454777389943"

@implementation MoreImageViewController{

UIImageView *imageView;

int imageIndex;

UIImage *image;

NSMutableArray *THreadArray;

}

-(void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

imageIndex = 100;

THreadArray = [NSMutableArray array];

self.edgesForExtendedLayout = 0;

//    创建多个UIImageView

for (int row = 0; row<3; row++) {

for (int list = 0; list<2; list++) {

imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10+list*200, 10+row*200, 195, 195)];

imageView.backgroundColor = [UIColor redColor];

imageView.tag = imageIndex++;

[self.view addSubview:imageView];

}

}

//    创建多个子线程

for (int index=0; index<6; index++) {

NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(thread:) object:@(index)];

[thread start];

[THreadArray addObject:thread];

}

}

//加载网络图片

-(void)thread:(NSNumber *)index{

[NSThread sleepForTimeInterval:[index intValue] ];

NSThread *thread = [NSThread currentThread];

if (thread.isCancelled==YES) {

[NSThread exit];

}

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kURRl]];

image = [UIImage imageWithData:data];

//    回到主线程

[self performSelectorOnMainThread:@selector(updateUI:) withObject:index waitUntilDone:YES];

}

//更新UI

-(void)updateUI:(NSNumber *)index{

imageView = [self.view viewWithTag:[index intValue]+100];

imageView.image = image;

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

//点击屏幕 取消未完成的线程

for (int dex = 0; dex<6; dex++) {

NSThread *thread = THreadArray[dex];

if (thread.isFinished == NO) {

[thread cancel];

}

}

//  NSLog(@"%@",THreadArray);

}

@end

时间: 2024-12-16 11:26:35

多线程通识的相关文章

将通识能力的提高融于日常学生和生活中

[来信] 非常感谢您前段时间的指点,让我有清晰的思路和方式知道如何去学习.只不过心中还有一点疑虑(抱歉麻烦您多次):前一段时间已经在跟网络安全实验室,学了些皮毛后又发觉自己依然喜欢开发.了解了多个方向和技术后,感觉我对计算机任何方向都有不错的兴趣(还是说因为未深入了解).感觉什么都想学,同时也想打好基础.包括您的很多老师和前辈说大学是通识的学习,要打好基础,具备学习各个方向的能力.可是问题是我是需要找工作的,谈到找工作大家又说应该专精一门技术,有自己的专长.这样的矛盾,你怎么看呢? [回复] 先

《哈佛通识教育红皮书》 哈佛委员会著

      <哈佛通识教育红皮书>哈佛委员会著 [内容简介] 1943年,哈佛大学众多学科领域里的12位著名教授组成委员会,旨在对"民主社会中的通识教育目标问题"进行研究.该委员会历经两年的潜心研究后,形成了以"民主社会中的通识教育"为题的总结报告,1945年由哈佛大学出版社出版,俗称"红皮书". [序言] 1.<哈佛通识教育红皮书>有助于我们在教育哲学层面上正确的理解高等教育要培养什么样的人以及如何培养这样的人才. 2.

尔雅通识题库系统

尔雅通识课 尔雅通识课题库 尔雅通识课作业 尔雅通识课答案 尔雅通识课题库系统 登录账户和密码即可查询课程题目的答案 登录入口 点击打开链接 http://erya.chinacloudsites.cn *注意使用必须尔雅课的账户密码登录 如下课程的题库 数据库中课程数目高达 100课! 题库数量超过10万题 后期会逐渐添加其他课程 敬请期待!

《经济学通识》一、前言

<经济学通识>的作者薛教授毕业于美国的乔治.梅森大学.这所大学的威名,来自于两位获得诺贝尔经济学奖的名师.一位是詹姆斯.布坎南,另一位是主弗农.史密斯.简单说一下两位大师.布坎南被称为经济学"公共选择学派"创始人,他倡导通过一致同意规则,构建宪政制度,实现经济效率与社会和谐.史密斯呢是通过引入实验方法,构建竞争性市场均衡.两位大师的研究领域都与现代经济体系中,政府制度与市场机制的关系紧密相关,这也使得乔治梅森大学称为美国著名的经济自由主义的学术堡垒. 我们继续说薛教授,我在

《经济学通识》有感

吕老师,您好.我是2016级计算机科学与技术网站建设的一名学生,我叫xxx,您题目的要求是我印象最深的某一堂课,而我想谈一谈我在<经济学通识>这堂课上的收获. 我先说一下我选这门课的初衷,主要有以下两点       我的专业是计算机科学与技术,以后就业的话八成也就是在IT圈混.×××总理早就提出了互联网+的计划,我想了解一下除了计算机以外其他学科的知识也对提升我的专业技能有所帮助吧,这是其一.       其二是我的一个学长给我推荐过吕老师的这门课,一个同学也推荐.本想大二下学期选,可是上学期

多线程通信笔试题

一道关于多线程通信的笔试题,个人觉得值得推荐.问题描述: 子线程循环10次,主线程循环100次,接着又回到子线程循环10次,接着又回到主线程循环100次.以此类推,总共循环50次.问题分析: 显然,这是一道多线程的问题.由于开启多个线程之后,是靠CPU分发时间片运行的,谁拿到时间片谁运行.但是可能A线程刚好运行到一半,时间片就给了B线程,这样就会导致数据产生错误.由此,我们用synchronized进行上锁,即便拿到时间片,但由于上锁的对象(即钥匙)别的线程没有释放,所以也只能干等,直到时间片又

读书笔记 - 《经济学通识》

扉页就写着“给 不同意我的朋友”,真不愧是经济学家的本色!序言就写人类至少要面对四种约束,从而对映出四种经济学理论,非常精彩!书里的亮点很多,作者是从芝加哥学派,推崇的是自由经济,以交易为基础用货币为手段,解释了大量的社会问题并提供了解决方法,让人拍案叫绝.尤其是学了这么多年,满分但仍似懂非懂的“价值”概念完全被推翻,不尽有种酣畅淋漓的感觉!以后就按照经济学理论中的“供求关系”和“个人估值”来思考,这两个怎么看都要简单有效的多!理论虽好,但应用于现实不禁有些学究气.例如涨价是短缺的体现,而涨价自

跟着实例学习java多线程5-初识volatile变量

同步机制可以保证原子操作和内存可见性,但是同步机制对变量的访问性能是我们不得不考虑的问题,java语言提供了一种弱同步机制,volatile变量. 它的原理大致是这样的,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将变量上的操作与其他内存操作一起重排序.volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量总会返回最新写入的值.(参考<java并发编程实践>一书) 让我们来看一个实例: package

【C++】泛型编程基础:模板通识

测试环境: Target: x86_64-linux-gnu gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2.1) 什么是泛型编程?为什么C++会有模板?这一切的一切都要从如何编写一个通用的加法函数说起. 很久很久以前 有一个人要编写一个通用的加法函数,他想到了这么几种方法: 使用函数重载,针对每个所需相同行为的不同类型重新实现它 int Add(const int &_iLeft, const int &_iRight) { retu