多线程(基础篇1)转载

在多线程这一系列文章中,我们将讲述C#语言中多线程的相关知识,在多线程(基础篇)中我们将学习以下知识点:

  • 创建线程
  • 中止线程
  • 线程等待
  • 终止线程
  • 确定线程的状态
  • 线程优先级
  • 前台线程和后台线程
  • 向线程传递参数
  • 使用C#的lock关键字锁定线程
  • 使用Monitor锁定线程
  • 处理异常

一、创建线程

  在整个系列文章中,我们主要使用Visual Studio 2015作为线程编程的主要工具。在C#语言中创建、使用线程只需要按以下步骤编写即可:

1、启动Visual Studio 2016,新建一个控制台应用程序。

2、确保该控制台程序使用.NET Framework 4.6或以上版本。然而在该篇中的所有示例使用较低版本可以正常工作。

3、双击打开该控制台应用程序中的“Program.cs”文件,在其中编写如下代码:

 1 using System;
 2 using System.Threading;
 3 using static System.Console;
 4
 5 namespace Recipe01
 6 {
 7     class Program
 8     {
 9         static void PrintNumbers()
10         {
11             WriteLine("Starting...");
12             for (int i = 1; i < 10; i++)
13             {
14                 WriteLine(i);
15             }
16         }
17
18         static void Main(string[] args)
19         {
20             Thread t = new Thread(PrintNumbers);
21             t.Start();
22             PrintNumbers();
23         }
24     }
25 }

4、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

  在第2行代码处,我们导入了System.Threading命名空间,该命名空间包含了我们编写多线程程序所需要的所有类型。

  在第3行代码处,我们使用了C# 6.0的using static特性,使用了该特性之后,在代码中允许我们在使用System.Console类型的静态方法的时候不需要指定其类型名。

  在第9~16行代码处,我们定义了一个名为“PrintNumbers”的方法,该方法将在“Main”方法和线程中进行调用。

  在第20行代码处,我们创建了一个线程来运行“PrintNumbers”方法,当我们初始化一个线程时,一个“ThreadStart”或“ParameterizedThreadStart”委托的实例被传递给线程的构造方法。

  在第21行代码处,我们启动线程。

  在第22行代码处,我们在“Main”方法中调用“PrintNumbers”方法。

二、中止线程

  在这一节,我们将让线程等待一些时间,在等待的这段时间内,该线程不会消耗操作系统的资源。编写步骤如下:

1、使用Visual Studio 2015创建一个新的控制台应用程序。

2、双击打开“Program.cs”文件,编写代码如下所示:

 1 using System;
 2 using System.Threading;
 3 using static System.Console;
 4 using static System.Threading.Thread;
 5
 6 namespace Recipe02
 7 {
 8     class Program
 9     {
10         static void PrintNumbers()
11         {
12             WriteLine("Starting...");
13
14             for(int i = 1; i < 10; i++)
15             {
16                 WriteLine(i);
17             }
18         }
19
20         static void PrintNumbersWithDelay()
21         {
22             WriteLine("Starting...");
23
24             for(int i = 1; i < 10; i++)
25             {
26                 Sleep(TimeSpan.FromSeconds(2));
27                 WriteLine(i);
28             }
29         }
30
31         static void Main(string[] args)
32         {
33             Thread t = new Thread(PrintNumbersWithDelay);
34             t.Start();
35             PrintNumbers();
36         }
37     }
38 }

3、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

  在第20~29行代码处,我们定义了一个新的方法“PrintNumbersWithDelay”,该方法将在我们新建的线程中运行。需要注意的是在第26行代码处,我们使用了“Thread”类的静态方法“Sleep”,该方法使得每次循环都会等待2秒钟执行。

  在第33行代码处,我们创建一个新的线程来运行“PrintNumbersWithDelay”方法。

三、线程等待

  在这一节中,我们将讲述如何在一个线程执行完毕后,再执行剩余的代码,要完成这个工作,我们不能使用Thread.Sleep方法,因为我们不知道另一个线程精确的执行时间。要使一个线程等待另一个线程执行完毕后再进行其他工作,只需要按下列步骤编写代码即可:

1、使用Visual Studio 2015创建一个新的控制台应用程序。

2、双击打开“Program.cs”文件,编写如下代码:

 1 using System;
 2 using System.Threading;
 3 using static System.Console;
 4 using static System.Threading.Thread;
 5
 6 namespace Recipe03
 7 {
 8     class Program
 9     {
10         static void PrintNumbersWithDelay()
11         {
12             WriteLine("Starting...");
13
14             for(int i = 1; i < 10; i++)
15             {
16                 Sleep(TimeSpan.FromSeconds(2));
17                 WriteLine(i);
18             }
19         }
20
21         static void Main(string[] args)
22         {
23             WriteLine("Starting...");
24             Thread t = new Thread(PrintNumbersWithDelay);
25             t.Start();
26             t.Join();
27             WriteLine("Thread completed");
28         }
29     }
30 }

3、运行该控制台应用程序,运行效果如下图所示:

  在第26行代码处,我们在“Main”方法中调用调用“t.Join”方法,该方法允许我们等待线程t执行完毕后,再执行“Main”方法中剩余的代码。有了该技术,我们可以同步两个线程的执行步骤。第一个线程等待第二个线程执行完毕后,再进行其他的工作,在第一个线程等待期间,第一个线程的状态为“bolcked”状态,和我们调用Thread.Sleep的状态一样。

四、终止线程

  在这一节中,我们将讲述如何终止另一个线程的执行。步骤如下:

1、使用Visual Studio 2015创建一个新的控制台应用程序。

2、双击打开“Program.cs”文件,编写如下代码:

 1 using System;
 2 using System.Threading;
 3 using static System.Console;
 4 using static System.Threading.Thread;
 5
 6 namespace Recipe04
 7 {
 8     class Program
 9     {
10         static void PrintNumbers()
11         {
12             WriteLine("Starting...");
13
14             for (int i = 1; i < 10; i++)
15             {
16                 WriteLine(i);
17             }
18         }
19
20         static void PrintNumbersWithDelay()
21         {
22             WriteLine("Starting...");
23             for (int i = 1; i < 10; i++)
24             {
25                 Sleep(TimeSpan.FromSeconds(2));
26                 WriteLine(i);
27             }
28         }
29
30         static void Main(string[] args)
31         {
32             WriteLine("Starting program...");
33             Thread t = new Thread(PrintNumbersWithDelay);
34             t.Start();
35             Thread.Sleep(TimeSpan.FromSeconds(6));
36             t.Abort();
37             WriteLine("A thread has been aborted");
38             t = new Thread(PrintNumbers);
39             t.Start();
40             PrintNumbers();
41         }
42     }
43 }

3、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

  在第36行代码处,我们调用了“t.Abort”方法,该方法用于终止一个线程的执行。当Abort方法被调用时,会对目标线程注入“ThreadAbortException”异常,该异常将导致线程的终止,这是一种非常危险的操作,因为这个异常可能发生在任何时候,并有可能导致整个应用程序的销毁。因此,不推荐使用Abort方法来终止一个线程的执行,我们可以向线程提供一个“CancellationToken”对象来取消一个线程的执行,这个技术我们将在后续讲述。

  未完待续!

时间: 2024-10-27 18:07:34

多线程(基础篇1)转载的相关文章

Linux C 程序设计多线程基础篇

   Linux C 程序设计多线程基础篇 题记:因为 Linux 网络入侵检测系统的设计与实现希望使用多线程,因此希望系统的学习一下 Linux C程序设计多线程的知识 注意事项:因为 pthraed 库不是 Linux 系统默认的库,因此在进行多线程开发的时候,需要加上头文件#include <pthread.h>,编译时要加参数 -lpthread;了:gcc thread.c -o thread -lpthread. 进程和线程: 进程是程序执行,资源分配的基本单位,每个进程都拥有自己

Spark性能优化指南——基础篇(转载)

前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团•大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性能更高. 然而,通过Spark开发出高性能的大数据计算作业,并不是那么简单的.如果没有对Spar

多线程-基础篇

线程概念 线程就是程序中单独顺序的流控制. 线程本身不能运行,它只能用于程序中. 说明:线程是程序内的顺序控制流,只能使用分配给程序的资源和环境. 进程 进程:执行中的程序. 程序是静态的概念,进程是动态的概念. 一个进程可以包含一个或多个线程. 一个进程至少要包含一个线程. 线程与进程的区别 多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响. 线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换负担比进程切换的负担要小.

并发编程之多线程基础篇及面试

线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务.通常由操作系统负责多个线程的调度和执行. 使用线程可以把占据时间长的程序中的任务放到后台去处理,程序的运行速度可能加快,在一些等待的任务实现上如用户输入.文件读写和网络收发数据等,线程就比较有用了.在这种情况下可以释放一些珍贵的资源如内存占用等等. 如果有大量

多线程基础篇(一)

线程之间方法区和堆内存共享,栈内存不共享;哪个线程调用sleep()方法,哪个线程就进入睡眠状态,与哪个对象调用该方法无关.start()方法的作用是创建一个线程的栈内存,该方法与普通方法相同,执行完立刻销毁. package test1; public class RacerRunnable implements Runnable{ /** * 龟兔赛跑多线程 */ public String winner; public void run() { for(int step = 1; step

Cadence PSpice 教程 基础篇(转载)

一.PSpice 的工作流程 二.PSpice A/D基本分析内容 在选择分析方法前需要绘制电路原理图, OrCAD 统一由 Capture 窗口进行输入和调 用 PSpice 分析.在使用 PSpice 时绘制原理图应该注意的地方. 1. 新建 Project 时应选择 Analog or Mixed-signal Circuit 2. 调用的器件必须有 PSpice 模型 首 先 , 调 用 OrCAD 软 件 本 身 提 供 的 模 型 库 , 这 些 库 文 件 存 储 的 路 径 为

[转载]前端工程——基础篇

特别声明:本文转载@云龙的<前端工程——基础篇>,感谢@云龙的分享. 喂喂喂,那个切图的,把页面写好就发给研发工程师套模板吧. 你好,切图仔. 不知道你的团队如何定义前端开发,据我所知,时至今日仍然有很多团队会把前端开发归类为产品或者设计岗位,虽然身份之争多少有些无谓,但我对这种偏见还是心存芥蒂,酝酿了许久,决定写一个系列的文章,试着从工程的角度系统的介绍一下我对前端,尤其是Web前端的理解. 只要我们还把自己的工作看作为一项软件开发活动,那么我相信读过下面的内容你也一定会有所共鸣. 前端,是

【转载】 Spark性能优化指南——基础篇

前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能复用同一个RDD 原则三:对多次使用的RDD进行持久化 原则四:尽量避免使用shuffle类算子 原则五:使用map-side预聚合的shuffle操作 原则六:使用高性能的算子 原则七:广播大变量 原则八:使用Kryo优化序列化性能 原则九:优化数据结构 资源调优 调优概述 Spark作业基本运行原理 资源参数调优 写在最后的话 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的

多线程(基础篇1)

在多线程这一系列文章中,我们将讲述C#语言中多线程的相关知识,在多线程(基础篇)中我们将学习以下知识点: 创建线程 中止线程 线程等待 终止线程 确定线程的状态 线程优先级 前台线程和后台线程 向线程传递参数 使用C#的lock关键字锁定线程 使用Monitor锁定线程 处理异常 一.创建线程 在整个系列文章中,我们主要使用Visual Studio 2015作为线程编程的主要工具.在C#语言中创建.使用线程只需要按以下步骤编写即可: 1.启动Visual Studio 2016,新建一个控制台