• 描述线程和进程的区别?
我们运行一个exe,就是一个进程实例,系统中有很多个进程。每一个进程都有自己的内存地址空间,每个地址相当于一个独立的边界,有自己独占的资源,进程之间不能共享代码和数据空间。(可用SendMessage实现进程之间消息传递)每一个进程有一个或多个线程,进程内多个线程可以共享所属进程的资源和数据,线程是操作系统调度的基本单元。线程是操作系统来调度和执行的。
当我们创建了一个线程后,线程里面到底有些什么东西呢?主要包括线程内核对象、线程环境块、1M大小的用户模式栈、内核模式栈。其中用户模式栈对于普通的系统线程那1M是预留的,在需要的时候才会分配,但是对于CLR线程,那1M一开始就分配了内存空间的。CLR线程是直接对应于一个Windows线程的。
还记得以前学校里学习的计算机课程里讲到,计算机的核心计算资源就是CPU核心和CPU寄存器,这也就是线程运行的主要战场。操作系统中那么多线程(一般都有上千个线程,大部分都处于休眠状态),对于单核CPU,一次只能有一个线程被调度执行,那么多线程怎么分配的呢?Winsows系统采用时间轮训机制,CPU计算资源以时间片(大约30ms)的实行分配给执行线程。 计算机资源(CPU核心和CPU寄存器)一次只能调度一个线程,具体的调度流程: 1.把CPU寄存器内的数据保存到当前线程内部(线程上下文等地方),给下一个线程腾地方;
2.线程调度:再线程集合里取出一个需要执行的线程;
3.加载新线程的上下文数据到CPU寄存器;
4.新线程执行,享受她自己的CPU时间片(大约30ms),完了之后继续回到第一步,继续轮回; 上面线程调度的过程,就是一次线程切换,一次切换就涉及到线程上下文灯数据的搬入搬出,性能开销很大的。因此线程不可滥用,线程的创建和消费也是和昂贵的,这也是为什么建议尽量使用线程池的一个主要原因。 对于Thread的使用太简单了,不重复了,总结一下线程的主要几点性能影响: 1、线程的创建、销毁时很昂贵的; 2.线程上下文切换有极大的性能开销,当然假如需要调度的新线程与当前是同一线程的话,就不需要线程上下文切换了,效率也要快很多。
3、这一点需要注意,GC执行回收时,首先(安全的)要挂起所有线程,遍历所以线程栈(根),GC回收后更新所有线程的根地址,再恢复线程调用,线程越多,GC要干的活就越多; 当然现在硬件的发展,CPU的核心越来越多,多线程技术可以极大提高应用程序的效率。但这也是必须在合理利用多线程技术的前提下,了解线程的基本原理,然后根据实际需求,好药注意相关资源环境,如磁盘IO、网络等情况综合考虑。
  • 为什么GUI不支持跨线程调用?有什么解决方法?
这是很多开发C/S客户端应用程序会遇到的问题,GUI程序的界面控件不允许跨县城访问,如果在其他线程中访问了界面控件,运行时就会抛出一个异常,就像下面的图示,是不是很熟悉,这其中的罪归祸首就是,就是“GUI的线程处理模型“,GUI应用程序(主要是Winform、wpf)引入了一个特殊线程处理模型,UI控件元素只能由创建它的线程访问和修改,微软这样处理是为了保证UI控件的线程安全。
为什么在UI线程执行一个耗时的计算操作,会导致UI假死呢?这个问题要追溯到Windows的消息机制了。 因为Windows是基于消息机制的,我们在UI上所有的键盘、鼠标操作都是以消息的形式发送给各个应用程序的。 GUI线程内部就有一个消息队列,GUI线程不断的循环处理这些消息,并根据消息更新UI的呈现。如果这个时候, 你让GUI线程去处理一个耗时的操作(比如花10秒去下载一个文件),那GUI线程就没办法处理消息独立饿了, UI界面就处于假死状态。
那我们该怎么办呢?不难想到使用线程,拿在线程里处理事件完成后,需要更新UI控件的状态,又该怎么办呢?
常用几种方式: 1.使用GUI控件提供的方法,Winform是控件的Invoke方法,wpf中控件的Dispatcher.Invoke方法
2.使用.net中提供的backgroundWorker执行耗时计算操作,在其任务完成事件RunWorkCompleted中更新UI控件
3.看上去很高大上的方法:使用GUI线程处理模型的同步上下文来送封UI控件修改操作,这样可以不需要调用UI控件元素
  • 前台线程和后台线程的区别
应用程序必须运行完所有的前台线程才可以退出,或者主动结束前台线程,不管后台线程是否还在运行,应用程序都会结束;对于后台线程,应用程序则不考虑是否已经运行完毕而直接退出,所以的后台线程在应用程序退出时自动结束。
通过将Thread.isBackground设置为True,就可以将线程指定为后台线程,主线程就是一个前台线程。
  • 说说常用的锁,lock是一种什么样的锁?
常用的如如SemaphoreSlim、ManualResetEventSlim、Monitor、ReadWriteLockSlim,lock是一个混合锁,其实质是Monitor
  • lock为什么要锁定一个参数(可否为值类型?)参数有什么要求?
lock的锁对象要求为一个引用类型。她可以锁定值类型,但值类型会被装箱,每次装箱后的对象都不一样,会导致锁定无效。
对于lock锁,锁定的这个对象参数才是关键,这个参数的同步索引块指针会指向一个真正的锁(同步块),这个锁(同步块)会被复用。
  • 多线程和异步的区别和联系
  • 线程池的优点和不足
线程池的使用是非常简单的,如下面的代码,把需要执行的代码提交到线程池,线程池内部会安排一个空闲的线程来执行你的代码,完全不用管理内部是如何进行线程调度的。

ThreadPool.QueqeUserWorkItem(t=>Console.WriteLine("Hello thread pool"));

每个CLR都有一个线程池,线程池在CLR内可以多个AppDomain共享,线程池是CLR内部管理的一个线程集合,初始是没有线程的,在需要的时候才会创建。线程池的主要结构图如下,基本流程如下:

 1.线程池内部维护一个请求列队,用于缓存用户请求需要执行的代码任务,就是Thread.QueqeUserWorkItem提交的请求;

 2.有新任务后,线程池使用空闲线程或者新线程来执行队列请求;

 3.任务执行完后线程不会销毁,留着重复使用;

 4.线程池自己负责维护线程的创建和销毁,但线程池有大量闲置的线程是,线程池会自动结束一部分多余的线程来释放资源;

线程池是有一个容量的,因为他是一个池子吗,可以设置线程池的最大活跃线程数,调用方法Threadpool.SetMaxThreads可是设置相关参数,但很多线程实践里都不建议程序猿们自己去设置这些参数,其实微软为了提高线程池性能,做了大量的优化,线程池可以很智能的确定是否要创建或者消费线程,大多数情况都可以满足需求了。线程池使得线程可以充分有效的被利用,减少了任务启动的延迟,也不用大量的去创建线程,避免了大量线程的创建和销毁对性能造成极大影响。

上面了解了线程的基本原理和诸多优点后,如果你是一个爱思考的猿类,应该会很容易的发现很多疑问,比如把任务添加到线程池队列后,怎么取消和挂起呢?如何知道他执行完了呢,下面来总结一下线程池的不足:

 1.线程池内的线程不支持线程的挂起、取消等操作,如想要取消线程池的任务,.net支持一种协作方式取消,使用起来也不少很方便,而且有些场景并不是很满足需求;

 2.线程内的任务没有返回值,也不知道何时执行完成;

 3.不支持设置线程的优先级,还包括其他类似需要对线程有更多的控制的需求也不支持;
  • Mutex和lock有什么不同?一般用哪一种比较好?
Mutex是一个基于内核模式的互斥锁,支持锁的递归调用,而Lock是一个混合锁,一般建议使用Lock更好,因为lock的性能更好。

多线程tips(面试常用)的更多相关文章

  1. php开发面试题---面试常用英语(你能介绍你自己吗?)

    php开发面试题---面试常用英语(你能介绍你自己吗?) 一.总结 一句话总结: Could you please describe yourself? 1.为什么觉得自己适合这份工作? Why do ...

  2. Java && Python 算法面试常用类以及方法总结

    数据结构 逻辑结构上: 包括集合,线性结构,非线性结构. 存储结构: 顺序存储,链式存储,索引存储,散列存储. Java 常见数据结构 大专栏  Java && Python 算法面试 ...

  3. 并发和多线程-说说面试长提平时少用的volatile

    说到volatile,一些参加过面试的同学对此肯定不陌生. 它是面试官口中的常客,但是平时的编码却很少打照面(起码,我是这样的). 最近的面试,我也经常会问到volatile相关的问题,比如volat ...

  4. Docker 入门 到部署Web 程序- (阿里面试常用的docker命令和优点)

    最近阿里的面试官问我Docker是做什么用的,我记得之前360和美团,京东的都问过,但是一直没时间看,最近有时间了,系统的学习了一下Docker,在此做一下记录,方便各位看官学习交流 一.Docker ...

  5. Java多线程基础(面试向)

    ----?为什么要用到多线程 CPU是以时间片的方式为进程分配CUP处理时间的,如果当一个进程同时要完成几件事的时候,如当从网上下载文件的时候,需要一边下载一边显示进度而且还要一边保存,如果按照单线程 ...

  6. Java多线程并发面试问答

    Java并发面试问答 什么是原子操作?Java并发API中的原子类是什么? 原子操作在单个任务单元中执行,而不受其他操作的干扰.在多线程环境中,原子操作是必需的,以避免数据不一致. int++不是原子 ...

  7. ios多线程开发的常用三种方式

    1.NSThread 2.NSOperationQueue 3.GCD NSThread: 创建方式主要有两种: [NSThread detachNewThreadSelector:@selector ...

  8. Python简单的多线程demo:常用写法

    简单多线程实现:启动50个线程,并计算执行时间. import threading import time def run(n): time.sleep(3) print("task:&qu ...

  9. Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier

    Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...

随机推荐

  1. [openjudge-动态规划]买书

    题目描述 描述 小明手里有n元钱全部用来买书,书的价格为10元,20元,50元,100元.问小明有多少种买书方案?(每种书可购买多本) 输入 一个整数 n,代表总共钱数.(0 <= n < ...

  2. MySql获取两个日期间的时间差

    [1]MySql 语言获取两个日期间的时间差 DATEDIFF 函数可以获得两个日期之间的时间差.但是,这个函数得出的结果是天数. 需要直接获取秒数可使用TIMESTAMPDIFF函数.应用示例如下: ...

  3. jfinal 项目 控制层、ORM层、AOP层,在发表之前一定要记得保存

    一.ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使用描述对象和数据 ...

  4. Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令

    Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令 今天写sh脚本发现一终止命令程序就停止运行了,检查了很久才发现后面少了个&字符导致的!错误写法:nohup ...

  5. DOM jquery

    DOM  文档对象模型(Document Object Model)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是,DOM ...

  6. build docker deivcemapper

    1.创建一个虚拟快设备 dd if=/dev/zero of=4G.img bs=1M count=4096 2.创建loop device 可以先用losetup -f 查看空闲的loop设备 lo ...

  7. SpringMVC中参数接收

    /** *  * SpringMVC中参数接收 * 1.接收简单类型 int String * 2.可以使用对象pojo接收 * 3.可以使用集合数据接收参数 * 页面: name="ids ...

  8. 2017第十三届湖南省省赛A - Seating Arrangement CSU - 1997

    Mr. Teacher老师班上一共有n个同学,编号为1到n. 在上课的时候Mr. Teacher要求同学们从左至右按1, 2, …, n的顺序坐成一排,这样每个同学的位置是固定的,谁没来上课就一目了然 ...

  9. Failed to connect to MySQL server as DBD::mysql module is not installed 问题的解决

    部署PXC ,卸了旧的MySQL perl-DBD-MySQL-4.013-3.el6.x86_64 这个包已经安装了,innobackup时一直在报错: Failed to connect to M ...

  10. Docker学习笔记之使用 Docker Hub 中的镜像

    0x00 概述 自己编写 Dockerfile 能够很好的实现我们想要的程序运行环境,不过如果装有我们想要环境的镜像已经由热心的开发者构建好并共享在 Docker Hub 上,直接使用它们就会远比自己 ...