多线程???【提高程序效率】(实现线程方式1、直接new2、通过线程池) 【应用场景:1、下载】

 同时开启多个线程,会造成CPU使用率过高。这个时候可以将线程休眠。从而避免多个线程抢占同一个资源而造成CPU过高。

start()开启线程

suspend()暂定线程

resume()恢复线程  无法实时得去暂定或者恢复线程(cpu是分片的2)

abort()终结线程,其实就是抛出一个异常

resetabort()把终结得线程再次启用,都会有延时

thread.priority=threadpriority.highest;是不是可以保证是优先执行?设置高优先级,只是一个概率提升

thread.isbackgroud=true;后台线程,进程结束,线程结束  thread.isbackgroud=false;前台线程,进程结束后,任务执行完毕后,线程才结束

  创建线程的几种方法     https://pan.baidu.com/s/13DsdA4iJtDRyZx1rkMx-sA?pwd=eyn1

 

描述线程与进程的区别?

 线程(Thread)与进程(Process)⼆者都定义了某种边界,不同的是进程定义的是应⽤程序与应⽤程序之间的边界,不同的进程之间不能共享代码和数据空间,⽽线程定义的是代码执⾏堆栈和执⾏上下⽂的边界。⼀个进程可以包括若⼲个线程,同时创建多个线程来完成某项任务,便是多线程。⽽同⼀进程中的不同线程共享代码和数据空间。⽤⼀个⽐喻来说,如果⼀个公司代表⼀个进程,在公司内部,各个成员就是线程,公司中的每个成员都有义务对公司的产值进⾏积累,同时也有权利对公司产值进⾏消费,当⾯对⼀个任务的时候,公司也可以派出⼏个成员来协同完成,⽽公司之外的⼈则没有办法直接 消费不属于⾃⼰公司的财产。

线程是操作系统中能够独立运行的最小单位,也是程序中能够并发执行的一段指令序列。

Windows单个进程所能访问的最⼤内存量是多少?它与系统的最⼤虚拟内存⼀样吗?这对于系统设计有什么影响?

这个需要针对硬件平台,公式为单个进程能访问的最⼤内存量=2的处理器位数次⽅/2,⽐如通常情况下, 32位处理器下,单个进程所能访问的最⼤内存量为:232 /2 = 2G 。单个进程能访问的最⼤内存量是最⼤虚拟内存的1/2,因为要分配给操作系统⼀半虚拟内存。

前台线程和后台线程有什么区别?

通过 Thread.IsBackground 属性设置为 true,就可以将线程指定为后台线程

前台线程应⽤必须结束掉所有的前台线程才能结束程序,只要有⼀个前台线程没退出进程就不会⾃动退出,当然线程是依附在进程上的,所以你直接把进程KO掉了的话⾃然所有前台线程也会退出。

后台线程进程可以不考虑后台直接⾃动退出,进程⾃动退出后所有的后台线程也会⾃动销毁。

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

不能,一个对象的一个synchronized方法只能由一个线程访问

sleep()和 wait() 有什么区别?

sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非

(a)“醒来”的线程具有更高的优先级

(b)正在运行的线程因为其它原因而阻塞。

wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。

什么是互斥?

 当多个线程访问同⼀个全局变量,或者同⼀个资源(⽐如打印机)的时候,需要进⾏线程间的互斥操作来保证 访问的安全性。

线程池?

由于线程的创建和销毁需要耗费一定的开销,过多的使用线程会造成内存资源的浪费,出于对性能的考虑,于是引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,然后委派给线程池的一个线程执行,线程执行完不会被立即销毁,这样既可以在后台执行任务,又可以减少线程创建和销毁所带来的开销。线程池线程默认为后台线程(IsBackground)。

线程池的有点和不⾜?

 优点:减⼩线程创建和销毁的开销,可以复⽤线程;也从⽽减少了线程上下⽂切换的性能损失;在GC回收时,较少的线程更有利于GC的回收效率。

 缺点:线程池⽆法对⼀个线程有更多的精确的控制,如了解其运⾏状态等;不能设置线程的优先级;加⼊到线程池的任务(⽅法)不能有返回值;对于需要⻓期运⾏的任务就不适合线程池。

如何查看和设置线程池的上下限?

线程池的线程数是有限制的,通常情况下,我们⽆需修改默认的配置。但在⼀些场合,我们可能需要了解线程池的上下限和剩余的线程数。线程池作为⼀个缓冲池,有着其上下限。在通常情况下,当线程池中的线程数⼩于线程池设置的下限时,线程池会设法创建新的线程,⽽当线程池中的线程数⼤于线程池设置的   上限时,线程池将销毁多余的线程。

PS:在.NET   Framework 4.0中,每个CPU默认的⼯作者线程数量最⼤值为250个,最⼩值为2个。⽽IO 线程的默认最⼤值为1000个,最⼩值为2个。 

在.NET中,通过 ThreadPool 类型提供的5个静态⽅法可以获取和设置线程池的上限和下限,同时它还额外地提供了⼀个⽅法来让程序员获知当前可⽤的线程数量,下⾯是这五个⽅法的签名:

① static void GetMaxThreads(out int workerThreads, out int completionPortThreads)

② static void GetMinThreads(out int workerThreads, out int completionPortThreads)

③ static bool SetMaxThreads(int workerThreads, int completionPortThreads)

④ static bool SetMinThreads(int workerThreads, int completionPortThreads)

⑤ static void GetAvailableThreads(out int workerThreads, out int completionPortThreads)

 Task状态机的实现和⼯作机制是什么?

CPS全称是Continuation Passing Style,在.NET中,它会⾃动编译为

1. 将所有引⽤的局部变量做成闭包,放到⼀个隐藏的状态机的类中

2. 将所有的await展开成⼀个状态号,有⼏个await就有⼏个状态号

3. 每次执⾏完⼀个状态,都重复回调状态机的MoveNext⽅法,同时指定下⼀个状态号

4. MoveNext⽅法还需处理线程和异常等问题。

await的作⽤和原理,并说明和GetResult()有什么区别?

 从状态机的⻆度出发,await的本质是调⽤Task.GetAwaiter()的UnsafeOnCompleted(Action)回调,并指定下⼀个状态号。从多线程的⻆度出发,如果await的Task需要在新的线程上执⾏,该状态机的MoveNext()⽅法会⽴即返回,此时,主线程被释放出来了,然后在UnsafeOnCompleted回调的action指定的线程上下⽂中继续MoveNext()和下⼀个状态的代码。⽽相⽐之下,GetResult()就是在当前线程上⽴即等待Task的完成,在Task完成前,当前线程不会释放。注意:Task也可能不⼀定在新的线程上执⾏,此时⽤GetResult()或者await就只有会不会创建状态机的区别了。

Task和Thread有区别吗?

 Task和Thread都能创建⽤多线程的⽅式执⾏代码,但它们有较⼤的区别。Task较新,发布于.NET 4.5, 能结合新的async/await代码模型写代码,它不⽌能创建新线程,还能使⽤线程池(默认)、单线程等⽅式编程,在UI编程领域,Task还能⾃动返回UI线程上下⽂,还提供了许多便利API以管理多个Task。

多线程有什么⽤?

(1) 发挥多核CPU的优势

随着⼯业的进步,现在的笔记本、台式机乃⾄商⽤的应⽤服务器⾄少也都是双核的,4核、8核甚⾄16核的  也都不少⻅,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的”多线程”那是假的多线程,同⼀时间处理器只会处理⼀段逻辑,只不过线程之间切换得⽐较 快,看着像多个线程”同时”运⾏罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时⼯作,多线程,可以真正发挥出多核CPU的优势来,达到充分利⽤CPU的⽬的。

 (2) 防⽌阻塞

 从程序运⾏效率的⻆度来看,单核CPU不但不会发挥出多线程的优势,反⽽会因为在单核CPU上运⾏多线 程导致线程上下⽂的切换,⽽降低程序整体的效率。但是单核CPU我们还是要应⽤多线程,就是为了防⽌  阻塞。试想,如果单核CPU使⽤单线程,那么只要这个线程阻塞了,⽐⽅说远程读取某个数据吧,对端迟 迟未返回⼜没有设置超时时间,那么你的整个程序在数据返回回来之前就停⽌运⾏了。多线程可以防⽌这个问题,多条线程同时运⾏,哪怕⼀条线程的代码执⾏读取数据阻塞,也不会影响其它任务的执⾏。

 (3) 便于建模

 这是另外⼀个没有这么明显的优点了。假设有⼀个⼤的任务A,单线程编程,那么就要考虑很多,建⽴整个 程序模型⽐较麻烦。但是如果把这个⼤的任务A分解成⼏个⼩任务,任务B、任务C、任务D,分别建⽴程序模型,并通过多线程分别运⾏这⼏个任务,那就简单很多了。

多线程和异步的区别和联系?

 多线程是实现异步的主要⽅式之⼀,异步并不等同于多线程。实现异步的⽅式还有很多,⽐如利⽤硬件的 特性、使⽤进程或纤程等。在.NET中就有很多的异步编程⽀持,⽐如很多地⽅都有Begin、End   的⽅法,就是⼀种异步编程⽀持,她内部有些是利⽤多线程,有些是利⽤硬件的特性来实现的异步编程。

在每个进程的内存空间中都会有一块特殊的公共区域,通常称为堆(内存)。进程内的所有线程都可以访问到该区域

线程安全指的是,在堆内存中的数据由于可以被任何线程访问到,在没有限制的情况下存在被意外修改的风险。即堆内存空间在没有保护机制的情况下,对多线程来说是不安全的地方,因为你放进去的数据,可能被别的线程“破坏”。

操作系统会为每个线程分配属于它自己的内存空间,通常称为栈内存,其它线程无权访问。这也是由操作系统保障的。

https://www.cnblogs.com/edisonchou/p/4848131.html

https://www.cnblogs.com/lixinjie/category/1458234.html

https://www.cnblogs.com/KnightsWarrior/archive/2010/07/21/1781852.html

https://blog.csdn.net/WuLex/article/details/122795214   异步方法同步调用