关键词:
在多线程这一系列文章中,我们将讲述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”对象来取消一个线程的执行,这个技术我们将在后续讲述。
未完待续!
多线程学习(基础篇)(代码片段)
文章目录一、多线程概述1.进程和线程之间的关系2.创建线程的方式3.Thread的几个常见属性4.中断一个线程5.获取当前线程引用6.线程的状态二、线程安全1.演示线程不安全2.如何避免线程安全问题3.synchronized关键字4.Java标准库中的线... 查看详情
多线程学习(基础篇)(代码片段)
文章目录一、多线程概述1.进程和线程之间的关系2.创建线程的方式3.Thread的几个常见属性4.中断一个线程5.获取当前线程引用6.线程的状态二、线程安全1.演示线程不安全2.如何避免线程安全问题3.synchronized关键字4.Java标准库中的线... 查看详情
多线程(基础篇3)
在上一篇多线程(基础篇2)中,我们主要讲述了确定线程的状态、线程优先级、前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程、使用Monitor锁定线程以及线程中的异... 查看详情
深入浅出多线程——线程基础篇
概述 多线程是java编程中非常重要的一块,在多核CPU时代,多线程是最直接提高程序执行效率的途径。所以学好多线程对我们极其重要。Java多线程的基本应用 创建多线程有两种方式: 1,继承Thread类/***@authoritunic.... 查看详情
多线程基础篇(代码片段)
线程之间方法区和堆内存共享,栈内存不共享;哪个线程调用sleep()方法,哪个线程就进入睡眠状态,与哪个对象调用该方法无关.start()方法的作用是创建一个线程的栈内存,该方法与普通方法相同,执行完立刻销毁.packagetest1;publicclassRacer... 查看详情
泥瓦匠聊并发编程:线程与多线程必知必会(基础篇)
本文目录线程与多线程线程的运行与创建线程的状态1线程与多线程线程是什么?线程(Thread)是一个对象(Object)。用来干什么?Java线程(也称JVM线程)是Java进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thr... 查看详情
多线程基础篇-javaee初阶-细节狂魔
文章目录前言线程是什么?Java中执行多线程编程下面我们在idea中实践准备工作:在idea中创建一个Java项目Thread类的基本方法拓展Thread类创建线程的写法1、最基本的创建线程的办法2、创建一个类实现Runnable接口,再创... 查看详情
java多线程系列---“基础篇”09之interrupt()和线程终止方式
...s.com/skywang12345/p/3479949.html(含部分修改)概要本章,会对线程的interrupt()中断和终止方式进行介绍。涉及到的内容包括:1.interrupt()说明2.终止线程的方式 2.1终止处于“阻塞状态”的线程 2.2终止处于“运行状态”... 查看详情
java多线程编程(基础篇)
一.进程和线程的区别: 进程:当前计算机正在运行的程序,进程是cpu分配资源的基本单位,一个进程至少有一个线程。 线程:计算机中任务调度和最小的执行单元,一个线程也被称为轻量级进程。  ... 查看详情
多线程基础
最近读了高洪岩的《Java多线程编程核心技术》一书,打算记录下多线程的基础知识点,也算对本书的一个读后感了。目前打算分四五篇博文进行记录。第一篇主要是记录线程的概念,创建,常用的基础方法等。1.什么是线程?通... 查看详情
多线程编程基础篇
...着计算机技术的发展,编程模型也越来越复杂多样化.但多线程编程模型是目前计算机系统架构的最终模型.随着CPU主频的不断攀升,X86架构的硬件已经成为瓶,在这种架构的CPU主频最高为4G.事实上目前3.6G主频的CPU已经接近了顶峰. ... 查看详情
java入门篇13--多线程
多线程是java并发的基础,我们先来学习一下吧:首先,让我们来起一个多线程,看看publicclassHelloWorld{publicstaticvoidmain(String[]args)throwsException{//lambda写法Threadt=newThread(()->{System.out.println("threadstart");try{Thread.sleep(1 查看详情
java---juc并发篇(多线程详细版)
Java---多线程1.并发基础(线程篇)1.1java线程状态及线程状态之间的转化1.2操作系统层面有5种状态2.线程池的核心参数(7个核心参数)2.1线程池参数介绍2.2代码实现2.3handler4种拒绝策略3.sleep与wait方法对比3.1异同点3... 查看详情
java---juc并发篇(多线程详细版)
Java---多线程1.并发基础(线程篇)1.1java线程状态及线程状态之间的转化1.2操作系统层面有5种状态2.线程池的核心参数(7个核心参数)2.1线程池参数介绍2.2代码实现2.3handler4种拒绝策略3.sleep与wait方法对比3.1异同点3... 查看详情
java多线程系列---“基础篇”06之线程让步
...9243.html (含部分修改)概要本章,会对Thread中的线程让步方法yield()进行介绍。涉及到的内容包括:yield()介绍yield()示例yield()与wait()的比较 一.yield()介绍yield()的作用是让步。它能让当前线程由“运行状态” 查看详情
java多线程系列---“基础篇”07之线程休眠
转自:http://www.cnblogs.com/skywang12345/p/3479256.html (含部分修改)概要本章,会对Thread中sleep()方法进行介绍。涉及到的内容包括: sleep()介绍 sleep()示例 sleep()与wait()的比较一.sleep()介绍sleep()定义在Thread.java中。slee 查看详情
java多线程系列---“基础篇”05之线程等待与唤醒
转自:https://www.cnblogs.com/skywang12345/p/3479224.html (含部分修改)概要本章,会对线程等待/唤醒方法进行介绍。涉及到的内容包括:wait(),notify(),notifyAll()等方法介绍wait()和notify()wait(longtimeout)和notify()wait()和notifyAll()为什么not 查看详情
java多线程(基础篇)(代码片段)
...文记录于阿里一群大佬们手码的书:《深入浅出Java多线程》线程与进程的区别:进程是一个独立的运行环境,而线程是在进程中执行的一个任务进程单独占有一定的内存地址空间,所以进程间存在内存隔离,... 查看详情