1、线程的定义
线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。
线程,在网络或多用户环境下,一个服务器通常需要接收大量且不确定数量用户的并发请求,为每一个请求都创建一个进程显然是行不通的,——无论是从系统资源开销方面或是响应用户请求的效率方面来看。因此, *** 作系统中线程的概念便被引进了。
线程,是进程的一部分,一个没有线程的进程可以被看作是单线程的。线程有时又被称为轻权进程或轻量级进程,也是 CPU 调度的一个基本单位。
2、线程的作用:
线程的作用很多,举个最为典型的例子:
当需要在网络上放一个服务端,一个客户端访问时,就会新建一个线程处理这个客户端的事务,这样的话只要不断新建线程就可以处理多个用户的请求了。
扩展资料
线程的五种状态:
1、新生状态(New)
当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后,此时该线程处于新生状态。 此时线程不是活着的(not alive);
2、就绪状态(Runnable)
通过调用线程实例的start()方法来启动线程使线程进入就绪状态;但还没有被分配到CPU,处于线程就绪队列;此时线程是活着的(alive)。
3、运行状态(Running)
一旦获取CPU,线程就进入运行状态,线程的run()方法才开始被执行,如果在给定的时间内没有执行结束,就会被系统给换下来回到线程的就绪状态,此时线程是活着的(alive)。
4、阻塞状态(Blocked)
通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞状态,此时线程是活着的(alive)。
5、死亡状态(Dead)
当一个线程的run()方法运行完毕或被中断或被异常退出,该线程到达死亡状态。处于Dead状态调用start()方法,会出现异常。
参考资料:
楼主可能对多线程还不是很熟悉。首先要处理大量数据必须放到除主线程外的其他工作线程中来处理,这样才能响应界面的点击、刷新、更新进度条等等。也就是说主线程是用来创建窗体、更新窗体等用户界面 *** 作的。
下面是转载的别人的,这样的资料太多了,其实仔细看看资料,其实很简单。
参考资料里面的内容很详细。
一、线程简介
通常C# 程序具有一个线程。这个线程从 Main方法的执行开始启动到Main方法的执行结束时线程终止。Main 直接或间接执行的每一个命令都由默认线程(或主线程)执行,当 Main 返回时此线程也将终止。不过,可以创建辅助线程,以便与主线程一起并行执行代码。这些线程通常称为“辅助线程”。
辅助线程可以用于执行耗时较多的任务或时间要求紧迫的任务,而不必占用主线程。例如,辅助线程经常用在服务器应用程序中,以便无需等待前面的请求完 成即可响应传入的请求。辅助线程还可用于在桌面应用程序中执行“后台”任务,以便使主线程(用于驱动用户界面元素)保持对用户 *** 作的响应。
多线程处理解决了吞吐量和响应性的问题,但同时也带来了资源共享问题,如死锁和争用状态。多线程特别适用于需要不同资源(如文件句柄和网络连接)的任务。为单个资源分配多个线程可能会导致同步问题,线程会被频繁阻止以等待其他线程,从而与使用多线程的初衷背道而驰。
常见的策略是使用辅助线程执行不需要大量占用其他线程所使用的资源的、耗时较多的任务或时间要求紧迫的任务。实际上,程序中的某些资源必须由多个线程访问。考虑到这些情况,SystemThreading 命名空间提供了用于同步线程的类。这些类包括 Mutex、Monitor、Interlocked、AutoResetEvent 和 ManualResetEvent。
您可以使用这些类中的部分或所有类来同步多个线程的活动,但是某些多线程处理支持由 C# 语言提供。例如,C# 中的 Lock 语句通过隐式使用 Monitor 来提供同步功能。
二、线程的生命周期
三、与线程有关的类
与C#有关的类都在SystemThreading命名空间中, SystemThreading 命名空间提供一些使得可以进行多线程编程的类和接口。除同步线程活动和访问数据的类(Mutex、Monitor、Interlocked、AutoResetEvent 等)外,此命名空间还包含一个 ThreadPool 类(它允许用户使用系统提供的线程池)和一个 Timer 类(它在线程池线程上执行回调方法)。
1 Thread: 创建并控制线程,设置其优先级并获取其状态。其中最常用的几个方法如下:
Sleep():将当前线程阻塞指定的毫秒数。
Abort():在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。
Join():阻塞调用线程,直到某个线程终止时为止。
Start():使线程得以按计划执行。
注意Suspend()为挂起线程和Resume()为继续挂起的线程,这两个方法存在风险,所以不建议使用。具体请参照MS的相关文档
Thread类的常用属性如下:
CurrentThread: 获取当前正在运行的线程。
IsAlive: 获取一个值,该值指示当前线程的执行状态。
Name: 获取或设置线程的名称
Priority:获取或设置一个值,该值指示线程的调度优先级。
ThreadState:获取一个值,该值包含当前线程的状态。
2 ThreadPool:提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。
BindHandle:将 *** 作系统句柄绑定到 ThreadPool。
GetAvailableThreads:检索由 GetMaxThreads 方法返回的最大线程池线程数和当前活动线程数之间的差值。
GetMaxThreads: 检索可以同时处于活动状态的线程池请求的数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用
GetMinThreads: 检索线程池在新请求预测中维护的空闲线程数。
QueneUserWorkItem: 将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
RegisterWaitForSingleObject: 注册正在等待 WaitHandle 的委托。
UnsafeQueueUserWorkItem: 注册一个等待 WaitHandle 的委托。
SetMaxThreads: 设置可以同时处于活动状态的线程池的请求数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。
四、示例及其说明
using System;
using SystemThreading;
public class Worker
{
// 在线程启动时此方法将被调用
public void DoWork()
{
while (!_shouldStop) // 如果线程正在运行则打印信息
{
ConsoleWriteLine("worker thread: working");
}
ConsoleWriteLine("worker thread: terminating gracefully");
}
public void RequestStop()
{
_shouldStop = true;
}
// Volatile这个关键字用来提醒编译器这个数据成员将被多线程访问
private volatile bool _shouldStop; // 应该停止
}
public class Program
{
static void Main()
{
// 创建一个线程对象 这里并不是线程的开始
Worker workerObject = new Worker();
// 这里定义一个新的线程,注意这里没有使用ThreadStart委托
// 另外构造函数接受的是对象的方法的名称
Thread workerThread = new Thread(workerObjectDoWork);
// 这里才是线程的真正开始
workerThreadStart();
ConsoleWriteLine("主线程: worker线程开始");
// 循环直到线程被激活,Thread的IsAlive这个属性表示线程是否为活动的
while (!workerThreadIsAlive);
// 将主线程暂停1毫秒,以允许worker这个线程完成自己的工作
ThreadSleep(1);
// 需要worker这个线程自动停止
workerObjectRequestStop();
// 使用Join这个方法来阻塞当前线程,直到对象的线程终止 workerThreadJoin();
ConsoleWriteLine("main thread: Worker thread has terminated");
}
}
Java中的线程的生命周期大体可分为5种状态。
1 新建(NEW):新创建了一个线程对象。
2 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
3 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:
(一) 等待阻塞:运行(running)的线程执行owait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二) 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三) 其他阻塞:运行(running)的线程执行Threadsleep(long ms)或tjoin()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
5 死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
线程的状态图:
你是要用VS 调试代码么? 如果是的话,你可以在每个线程的执行函数中按F9设断点,程序运行到断点处是观察窗口上方 “Thread”文本框里面的内容,这里写的就是当前程序运行的线程的ID。 你如果不调试,直接运行的话,只能在每个线程中添加输出的语
线程的五种状态: 1新建(new) 用new语句创建的线程对处于新建状态,此时它和其它Java对象一样,仅仅在Heap中被分配了内存。当一个线程处于新建状态时,它仅仅是一个空的线程对象,系统不为它分配资源。 Thread t = new Thread(new Runner()); 2就绪(Runnable) 程序通过线程对象调用启动方法start()后,系统会为这个线程分配它运行时所需的除处理器之外的所有系统资源。这时,它处在随时可以运行的状态,在随后的任意时刻,只要它获得处理器即会进入运行状态。 tstart() 3运行(Running) 处于这个状态的线程占用CPU,执行程序代码。在并发环境中,如果计算机只有一个CPU,那么任何时刻只会有一个线程处于这个状态。如果计算机中有多个CPU,那么同一时刻可以让几个线程占用不同的CPU,使它们都处于运行状态,只有处于就绪状态的线程才有机会转到运行状态。 4阻塞(Blocked) 阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到运行状态。 阻塞状态可分为以下3种: ●位于对象等待池中的阻塞状态(Blocked in object's wait pool):当线程处于运行状态时,如果执行了某个对象的wait()方法,Java虚拟机就会把线程放到这个对象的等待池中。 ●位于对象锁池中的阻塞状态(Blocked in object's lock pool):当线程处于运行状态,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java虚拟机就会把这个线程放到这个对象的锁池中。 ●其他阻塞状态(Otherwise Blocked):当前线程执行了sleep()方法,或者调用了其他线程的join()方法,或者发出了I/O请求时,就会进入这个状态。 当一个线程执行Systemoutprintln()或者Systeminread()方法时是,就会发出一个I/O请求,该线程放弃CPU,进入阻塞状态,直到I/O处理完毕,该线程才会恢复执行。 5死亡(Dead) 当线程退出run()方法时,就进入死亡状态,该线程结束生命周期。线程有可能是正常执行完run()方法而退出,也有可能是遇到异常而退出。不管线程是正常结束还是异常结束,都不会对其他线程造成影响。
itjobJava老师讲过:1)线程堆栈概述及基础知识
2)线程堆栈的生成原理以及相关工具
3)不同JVM线程堆栈的格式的差异(SunHotSpot、IBMJRE、OracalJRockit)
4)线程堆栈日志介绍以及解析方法
5)线程堆栈的分析和相关的技术
6)常见的问题模板(线程竟态、死锁、IO调用挂死、垃圾回收/问题、死循环等)
7)线程堆栈问题实例分析
我希望这一系列的培训能给你带来确实的帮助,所以请持续关注每周的文章更新。
但是如果我在学习过程中有疑问或者无法理解文章中的内容该怎么办?
不用担心,把我当做你的导师就好。任何关于线程堆栈的问题都可以咨询我(前提是问题不能太low)。请随意选择下面的几种方式与我取得联系:
1)直接本文下面发表评论(不好意思的话可以匿名)
2)将你的线程堆栈数据提交到RootCauseAnalysisforum
3)发Email给我,地址是@@hotmail
能帮我分析我们产品上遇到的问题么?
当然可以,如果你愿意的话可以把你的堆栈现场数据通过邮件或论坛RootCauseAnalysisforum发给我。处理实际问题是才是学习提升技能的王道。
我真心期望大家能够喜欢这个培训。所以我会尽我所能去为你提供高质量的材料,并回答大家的各种问题。
在介绍线程堆栈分析技术和问题模式之前,先要给大家讲讲基础的内容。所以在这篇帖子里,我将先覆盖到最基本的内容,这样大家就能更好的去理解JVM、中间件、以及JavaEE容器之间的交互。
JavaVM概述
Java虚拟机是JaveEE平台的基础。它是中间件和应用程序被部署和运行的地方。
JVM向中间件软件和你的Java/JavaEE程序提供了下面这些东西:
_(二进制形式的)Java/JavaEE程序运行环境
_一些程序功能特性和工具(IO基础设施,数据结构,线程管理,安全,监控等等)
_借助垃圾回收的动态内存分配与管理
你的JVM可以驻留在许多的 *** 作系统(Solaris,AIX,Windows等等)之上,并且能根据你的物理服务器配置,你可以在每台物理/虚拟服务器上安装1到多个JVM进程
JVM与中间件之间的交互
下面这张图展示了JVM、中间件和应用程序之间的高层交互模型。
如你所见,标准JavaEE应用程序的线程的分配实在中间件内核与JVM之间完成的。(当然也有例外,应用程序可以直接调用API来创建线程,这种做法并不常见,而且在使用的过程中也要特别的小心)
同时,请注意一些线程是由JVM内部来进行管理的,典型的例子就是垃圾回收线程,JVM内部使用这个线程来做并行的垃圾回收处理。
因为大多数的线程分配都是由JavaEE容器完成的,所以能够理解和认识线程堆栈跟踪,并能从线程堆栈数据中识别出它来,对你而言很重要这可以让你能够快速的知道JavaEE容器正要执行的是什么类型的请求
从一个线程转储堆栈的分析角度来看,你将能了解从JVM发现的线程池之间的不同,并识别出请求的类型
最后一节会向你提供对于HotSopVM而言什么是JVM线程堆栈的一个概述,还有你将会遇到的各种不同的线程而对IBMVM线程堆栈形式详细内容将会在第四节向你提供
请注意你可以从根本原因分析论坛获得针对本文的线程堆栈示例
JVM线程堆栈——它是什么
JVM线程堆栈是一个给定时间的快照,它能向你提供所有被创建出来的Java线程的完整清单
返回对当前正在执行的线程对象的引用。
简单来说就是 Tthread类(线程类) 中的一个方法 ThreadcurrentThread() 是指获取当前运行的线程对象 例如:
ThreadcurrentThread()getName() 就是获取当前运行的线程的名称 简单来说这就差不多了
以上就是关于什么是线程有什么用 讲得通俗点全部的内容,包括:什么是线程有什么用 讲得通俗点、C#大数据量问题、线程状态有哪些,它们之间是如何转换的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)