c#之线程总结(一)
时间:2022-04-25
本文章向大家介绍c#之线程总结(一),主要内容包括1 线程之委托方法、2为线程传递参数、3同步控件、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
在我们做项目的时候会经常用到线程,但线程也不是万能的,用线程需要注意的东西也很多,自己做了一下总结
这次总结主要说三个部分
我们先看一下小例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadMethod
{
class Program
{
static void Main(string[] args)
{
ThreadStart _ts = new ThreadStart(MyThread);
Thread _thread1 = new Thread(_ts);
_thread1.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
public static void MyThread()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i + " by Thread " + Thread.CurrentThread.ManagedThreadId);
}
}
}
}
1 线程之委托方法
在方法里我们定义了一个 ThreadStart _ts = new ThreadStart(MyThread);
打开msdn 查看发现这是一个委托 ,表示在 Thread 上执行的方法。
[ComVisible(true)]
public delegate void ThreadStart();
那就是说也可以这么写
Thread _thread2 = new Thread(delegate()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i + " by Thread " + Thread.CurrentThread.ManagedThreadId);
}
});
//或者
Thread _thread3 = new Thread(()=>
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i + " by Thread " + Thread.CurrentThread.ManagedThreadId);
}
});
_thread2.Start();
_thread3.Start();
2为线程传递参数
Thread类有一个带参数的委托类型的重载形式
[ComVisibleAttribute(false)]
public delegate void ParameterizedThreadStart (
Object obj
)可以传递一个object参数,因为是个委托我们也可以和上面的那么写
class Program
{
static void Main(string[] args)
{
Thread _thread = new Thread(new ParameterizedThreadStart(MyParametFun));
_thread.Start("aaa");
Thread _thread2 = new Thread(x => { Console.WriteLine(x); });
_thread2.Start("bbb");
Console.WriteLine("other Metod");
Console.ReadLine();
}
public static void MyParametFun(object f_str)
{
Console.WriteLine(f_str);
}
}
有时个我们有好几个参数只传一个参数据就不能满足了
我们可以直接用委托要多个参数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadMethod
{
class Program
{
static void Main(string[] args)
{
int _x = 1;
string _str = "abc";
string _str2 = "aaaaa";
Thread _thread=new Thread(()=>{
Console.WriteLine(_x);
Console.WriteLine(_str);
Console.WriteLine(_str2);
});
_thread.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
}
}
也可以自己写一个中间类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadMethod
{
class Program
{
static void Main(string[] args)
{
MyMode _myMode = new MyMode(1, "aa", "bb");
Thread _thread = new Thread(_myMode.ConsoFun);
_thread.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
}
public class MyMode
{
int _x ;
string _str ;
string _str2 ;
public MyMode() { }
public MyMode(int f_x,string f_str1,string f_str2)
{
_x = f_x;
_str = f_str1;
_str2 = f_str2;
}
public void ConsoFun()
{
Console.WriteLine(_x);
Console.WriteLine(_str);
Console.WriteLine(_str2);
}
}
}
3同步控件
三种方法lock 和Monitor 还有MethodImpl都会让线程同步下面我们一个一个的来说
多个线程访问同一个方法时有可能会出现一个线程修改了一个参数别一个线程进入也修改了这个参数就会发生
错误
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadMethod
{
class Program
{
static int sum = 200;
static void Main(string[] args)
{
Thread _t1 = new Thread(ConFun);
Thread _t2 = new Thread(ConFun);
_t1.Start();
_t2.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
public static void ConFun()
{
int i = 0;
while (i <= 10)
{
sum -= i;
Thread.Sleep(10);
++i;
}
Console.WriteLine(sum);
}
}
}
结果是
根据机器的配制不同可能结果也不同
在这个方法里我们是想让第一个线程减10结果应该 是145
第二个线程进去后在145基础上再减结果应该是90
现在说三种方法lock 和Monitor 还有MethodImpl 都会让线程同步,只有一个线程执行完后另一个线程才能访问
我们一个一个来说吧
先看一下lock
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.CompilerServices;
namespace ThreadMethod
{
class Program
{
static object obj = new object();
static int sum = 200;
static void Main(string[] args)
{
Thread _t1 = new Thread(ConFun);
Thread _t2 = new Thread(ConFun);
_t1.Start();
_t2.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
public static void ConFun()
{
lock (obj)
{
int i = 0;
while (i <= 10)
{
sum -= i;
Thread.Sleep(10);
++i;
}
}
Console.WriteLine(sum);
}
}
}
这样结果就对了吧
还有其它的两种形式
用MethodImpl 要加上
using System.Runtime.CompilerServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.CompilerServices;
namespace ThreadMethod
{
class Program
{
static object obj = new object();
static int sum = 200;
static void Main(string[] args)
{
Thread _t1 = new Thread(ConFun);
Thread _t2 = new Thread(ConFun);
_t1.Start();
_t2.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
[MethodImpl(MethodImplOptions.Synchronized)]
public static void ConFun()
{
int i = 0;
while (i <= 10)
{
sum -= i;
Thread.Sleep(10);
++i;
}
Console.WriteLine(sum);
}
Monitor
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadMethod
{
class Program
{
static object obj = new object();
static int sum = 200;
static void Main(string[] args)
{
Thread _t1 = new Thread(ConFun);
Thread _t2 = new Thread(ConFun);
_t1.Start();
_t2.Start();
Console.WriteLine("other Metod");
Console.ReadLine();
}
public static void ConFun()
{
Monitor.Enter(obj);
int i = 0;
while (i <= 10)
{
sum -= i;
Thread.Sleep(10);
++i;
}
Monitor.Exit(obj);
Console.WriteLine(sum);
}
}
}
结果都是正确的
- hdu----(1671)Phone List(Trie带标签)
- PHP-数组
- hdu---1506(Largest Rectangle in a Histogram/dp最大子矩阵)
- 日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url
- golang使用sort接口实现排序示例
- hdu----(5056)Boring count(贪心)
- hdu----(5055)Bob and math problem(贪心)
- hadoop3.0 Yarn支持网络资源:network原理设计文档说明【中文】
- PHP-超级全局变量
- 日志分析实战之清洗日志小实例5:实现获取不能访问url
- CentOS安装Redis、PHPredis扩展
- 日志分析实战之清洗日志小实例4:统计网站相关信息
- PHP-数组排序
- hdu---(3555)Bomb(数位dp(入门))
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- R语言中GLM(广义线性模型),非线性和异方差可视化分析
- 解决java的http请求库dongliu.requests请求结果中文乱码的问题
- 保姆级教程,手把手教你实现一个SpringBoot的starter
- 微服务[学成在线] day05:消息中间件 RabbitMQ
- 微服务[学成在线] day06:页面发布以及课程管理
- 微服务[学成在线] day07:课程管理开发
- 微服务[学成在线] day08:FastDFS 实现课程图片管理
- 【MySQL入门】之细说脏读、幻读及不可重复读
- 微服务[学成在线] day09:Eureka、Feign、课程预览实现
- 【MySQL入门】之MySQL数据库的锁机制(一)
- 【MySQL入门】之MySQL数据库的锁机制(二)
- 【MySQL】删库别着急跑路(一)--Xtrabackup的原理及使用
- 微服务[学成在线] day11:基于 ElasticSearch 构建搜索服务
- 【MySQL】删库别着急跑路(二)--mysqldump的使用
- 【MySQL】删库别着急跑路(三)--binlog2sql闪回工具的使用