c# 多线程概览
场景:1~1000累加求和
只考虑如何启用多线程计算,不考虑线程同步
实现方式:
1.Thread thread=new Thread(new ThreadStart(some delegate)); 无参数启动新线程。
2.Thread thread=new Thread(new ParameterizedThreadStart(some delegate,params)); 带参数启动新线程。
3.将线程操作封装为一个独立方法,其中使用匿名方法的方式将外部参数导入。
4.ThreadPool.QueueUserWorkItem(delegeate,params)带参数的线程池方法,
注意线程池中分配的线程都是background线程,主线程终止会导致子线程终止。
5.Task,都多重方式,底层使用的Threadpool,需要使用wait方法阻塞主线程。
6.构造一个包含参数、操作的类,通过类的属性将参数传递给操作。
7.通过委托的方式,可以传参,并且可以有返回值。
以上除了委托方式,其他可以传参的方式,都可以通过把返回值封装在参入参数中,使用引用的方式获得返回值。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace multithreadTest
{
class Program
{
static Stopwatch watch = new Stopwatch();
static int length = 100;
static int count;
static void Main(string[] args)
{ Console.WriteLine("Main Thread:{0}", Thread.CurrentThread.ManagedThreadId);
//CaculateSum();
//NoInputAndReturn();
//MultiInputNoReturn_Anonymous();
//MultiInputNoReturn_ParameterizedThread();
//MultiInputNoReturn_ThreadPool();
MultiInputNoReturn_Task();
//MultiInputNoReturn_UseClassProperty();
//MultiInputWithReturn_Delegate();
Console.WriteLine("Main Thread Exit:{0}", Thread.CurrentThread.Name);
} #region 没有输入,没有返回
/// <summary>
/// 没有输入,没有返回
/// </summary>
public static void NoInputAndReturn()
{
ThreadStart ts = new ThreadStart(CaculateSum);
Thread thread=new Thread(ts);
thread.Start();
} /// <summary>
/// 1~1000求和 无输入 无返回
/// </summary>
public static void CaculateSum()
{
watch.Reset();
watch.Start();
Console.WriteLine("IsBackground:{0}", Thread.CurrentThread.IsBackground);
Console.WriteLine("Thread Start:{0}", Thread.CurrentThread.ManagedThreadId);
int count = 0;
for (var i = 0; i <= 1000; i++)
{
count += i;
Thread.Sleep(5);
}
watch.Stop();
Console.WriteLine("Thread Exit:{0},Count:{1},Time:{2}", Thread.CurrentThread.ManagedThreadId, count, watch.Elapsed);
}
#endregion #region 多输入 无返回
#region 匿名方法
/// <summary>
/// 多输入 无返回 匿名方法
/// </summary>
public static void MultiInputNoReturn_Anonymous()
{
for(var i=0;i<1000;i+=(length+1))
{
CaculateSum_Anonymous(i, i + length > 1000 ? 1000 : i + length);
}
} /// <summary>
/// start~end求和 匿名方法方式
/// </summary>
/// <returns></returns>
public static void CaculateSum_Anonymous(int start, int end)
{
Thread t = new Thread(new ThreadStart(delegate() {
watch.Reset();
watch.Start();
int count = 0;
for (var i = start; i <= end; i++)
{
count += i;
Thread.Sleep(5);
}
watch.Stop();
Console.WriteLine("Thread Exit:{0},Count:{1},Time:{2}", Thread.CurrentThread.ManagedThreadId, count, watch.Elapsed);
}));
t.Start();
}
#endregion class StartEnd
{
public int start;
public int end;
} #region ParameterizedThread包装参数 public static void MultiInputNoReturn_ParameterizedThread()
{
for (var i = 0; i < 1000; i += (length+1))
{
ParameterizedThreadStart ts = new ParameterizedThreadStart(CaculateSum_ParameterizedThread);
Thread thread = new Thread(ts);
thread.Start(new StartEnd() { start = i, end = i + length > 1000 ? 1000 : i + length });
}
} /// <summary>
/// 0~end求和 一个参数 无返回
/// </summary>
/// <returns></returns>
public static void CaculateSum_ParameterizedThread(object se)
{
watch.Reset();
watch.Start();
var start=((StartEnd)se).start;
var end=((StartEnd)se).end;
int count = 0;
for (var i =start ; i <= end; i++)
{
count += i;
Thread.Sleep(5);
}
watch.Stop();
Console.WriteLine("Thread Exit:{0},Count:{1},Time:{2}", Thread.CurrentThread.ManagedThreadId, count, watch.Elapsed);
}
#endregion #region ThreadPool 包装参数
public static void MultiInputNoReturn_ThreadPool()
{
for (var i = 0; i < 1000; i += (length + 1))
{
ThreadPool.QueueUserWorkItem(CaculateSum_ParameterizedThread,
new StartEnd() { start = i, end = i + length > 1000 ? 1000 : i + length });
} //threadpool中的线程都是background的,如果主线程提前终止,会终止子线程的操作
Console.WriteLine("Main thread does some work, then sleeps.");
Thread.Sleep(5000); Console.WriteLine("Main thread exits.");
}
#endregion #region Task 包装参数
public static void MultiInputNoReturn_Task()
{
for (var i = 0; i < 1000; i += (length + 1))
{
Task t = new Task(CaculateSum_ParameterizedThread, new StartEnd() { start = i, end = i + length > 1000 ? 1000 : i + length });
t.Start();
//Task是基于线程池的,如果不使用wait会被主线程终止
t.Wait();
}
Console.WriteLine("Main thread does some work, then sleeps."); Console.WriteLine("Main thread exits.");
}
#endregion #region 通过类属性
/// <summary>
/// 多输入 无返回 通过类属性
/// </summary>
public static void MultiInputNoReturn_UseClassProperty()
{
for (var i = 0; i < 1000; i += (length+1))
{
var sum = new SumTest();
ThreadStart start = new ThreadStart(sum.GetSum);
sum.Start = i;
sum.End = i + length > 1000 ? 1000 : i + length;
Thread t = new Thread(start);
t.Start();
}
} public class SumTest
{
public int Start;
public int End; public void GetSum()
{
watch.Reset();
watch.Start();
int count = 0;
for (var i = this.Start; i <= this.End; i++)
{
count += i;
Thread.Sleep(5);
}
watch.Stop();
Console.WriteLine("Thread Exit:{0},Count:{1},Time:{2}", Thread.CurrentThread.ManagedThreadId, count, watch.Elapsed);
}
} #endregion
#endregion #region 传参 有返回 委托 delegate TimeSpan GetSumMethod(int start, int end);
static GetSumMethod getSum;
public static void MultiInputWithReturn_Delegate()
{
int count=0;
TimeSpan ts = new TimeSpan();
for (var i = 0; i < 1000; i += (length+1))
{
GetSumMethod getSumMethod = CaculateSum;
getSumMethod.BeginInvoke(i, i + length > 1000 ? 1000 : i + length,
new AsyncCallback(delegate(IAsyncResult result) { ts += getSumMethod.EndInvoke(result); }), null);
} Thread.Sleep(6000);
Console.WriteLine("TimeSpan:{0}", ts);
Console.ReadKey();
} public static TimeSpan CaculateSum(int start, int end)
{
watch.Reset();
watch.Start();
Console.WriteLine("Thread Start:{0}", Thread.CurrentThread.ManagedThreadId);
int count = 0;
for (var i = start; i <= end; i++)
{
count += i;
Thread.Sleep(5);
}
watch.Stop();
Console.WriteLine("Thread Exit:{0},Count:{1},Time:{2}", Thread.CurrentThread.ManagedThreadId, count, watch.Elapsed);
return watch.Elapsed;
} #endregion }
}
c# 多线程概览的更多相关文章
- iOS 多线程详解
iOS开发 多线程 概览 机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发: 对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其 ...
- 【Java多线程】线程同步方法概览
一:使用syncrhoized内置锁实现同步 使用互斥来实现线程间的同步,保证共享数据在同一时刻只被一个线程使用.Java中最基本的互斥手段就是syncrhoized关键字. syncrhoized的 ...
- C# - 多线程 之 信号系统
基础概览 多线程之信号系统命名空间 using System.Threading; 线程同步类的继承层次关系图 终止状态和非终止状态 在终止状态下,被WaitOne()阻塞的线程会逐个得到释放.如果一 ...
- Zookeeper C API 指南四(C API 概览)(转)
上一节<Zookeeper C API 指南三(回调函数)>重点讲了 Zookeeper C API 中各种回调函数的原型,本节将切入正题,正式讲解 Zookeeper C API.相信大 ...
- iOS多线程开发
概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...
- Java并发编程实现概览
并发概览 >>同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通 ...
- 转:Linux网络IO并行化技术概览
转:http://codinginet.com/articles/view/201605-linux_net_parallel?simple=1&from=timeline&isapp ...
- C#与C++、Java之比较概览
转自C#与C++.Java之比较概览 C#与C++.Java之比较概览 Ben Albahari 著 荣耀 译 本文翻译时间较早.欢迎指出任何误失.谢谢. 感谢以下人士的支持和反馈(按字母先后顺序) ...
- OSG开发概览(转载)
OSG开发概览 1 OSG基础知识 Ø OSG是Open Scene Graphic 的缩写,OSG于1997年诞生于以为滑翔机爱好者之手,Don burns 为了对滑翔机的飞行进行模拟,对open ...
- java多线程一览
线程概述: 多线程的目的,不是提高程序的执行速度,而是提高程序的使用率(能抢到CPU的可能比较大). 因为线程是CPU调度的基本单位,所以,当一个程序的线程较多的时候就更容易抢到cpu的资源 进程: ...
随机推荐
- GB28181安防Web无插件流媒体平台LiveGBS如何配置集群部署增加并发播放和录像
@ 目录 1.信令服务 2.流媒体服务 2.1 流媒体节点一配置示例 2.2 流媒体节点二配置示例 3.部署资源及说明 3.1.安装包 3.2.使用说明 1.信令服务 信令服务 和 流媒体服务 之间是 ...
- 安防摄像通过GB28181协议实现云端录像存储与回放
GB28181流媒体云端录像存储 区别于数字硬盘摄像机通过GB28181的实时录像查询,有的时候,需要将普通的GB28181国标摄像机或设备的视频在云端录像存储,LiveGBS支持这种云端存储解决方案 ...
- 解码C语言位字段
一.位字段的定义 位字段允许在结构体中按 位(bit) 为单位分配成员空间,用于紧凑存储布尔标志或小范围整数值,节省内存.常用于硬件寄存器操作.协议数据解析等场景. 二.位字段的语法 1. 基本声明 ...
- Java第一次预习总结与问题
1. 本章学习总结 Java的基本数据类型和引用数据类型的基本认识 Java的基本认识 2. 书面作业 Q1 使用Java能编写哪些类型的程序?试举至少两个例子. 游戏开发:我的世界 移动应用开发 Q ...
- 买涨不买跌 选PC就要选“智慧”
还未进入十一月,各大电商平台和消费者就已经沸腾起来了.今年"双十一"最大的特点就是"真低价",即真好货+真优惠."真低价"的背后,是因为消费 ...
- 独立三年,卷王Redmi率先破局存量时代
年度口碑旗舰芯片天玑8100.首个获得DisplayMate A+屏幕认证的LCD 屏幕.1亿像素高清摄像头.120W快充.新一代"蓝牙5.3"...... 如此配置的手机你觉得会 ...
- 保姆级教程:手把手教你搭建vue3+vite+pinia项目,直接上手开发
虽然代码很机械的就写出来了,但是搭建项目却总是很生疏会忘记呢(毕竟一个项目做n年..) 方法一:使用vite生成项目 第一步:npm create vite projectName(你的项目名) 第二 ...
- 创建一个VUE项目,正式开发之前要做的配置~
一.使用vue-cli脚手架创建一个项目,根据我们开发所需生成固定的文件目录(可配置). 二.创建好项目之后,还并不能开始真正的开发,我们需要做一些开发前的准备,比如请求的axios封装,多环境的地 ...
- macro lef编写时的注意事项
做macro lef的时候基本的flow以前写博客时简单介绍过,详见这篇. 还有一些小的tips要注意,直接用virtuoso出的lef并不完善. MACRO macro CLASS BLOCK ; ...
- 开发日常记录MCP Server:Playwright 浏览器自动化
最近在研究如何让大语言模型(LLM)更高效地操作网页,发现了 Playwright MCP 这个神器.它基于 Playwright 实现了浏览器自动化的 MCP 协议,能让 LLM 通过结构化数据与网 ...