博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程系列02,多个线程同时处理一个耗时较长的任务以节省时间
阅读量:5281 次
发布时间:2019-06-14

本文共 2898 字,大约阅读时间需要 9 分钟。

当面对一个耗时较长的任务时,我们可以把这个任务切分成多个部分,然后同时交给多个线程处理。

 

□ 统计字节数组一个比较耗时的方式

以下来统计一个字节数组的大小。

 
class Program
{
static byte[] values = new byte[500000000];
static void Main(string[] args)
{
GenerateByteArray();
Console.WriteLine("正在统计字节数");
Stopwatch watch = new Stopwatch();
watch.Start();
long total = 0;
for (int i = 0; i < values.Length; i++)
{
total += values[i];
}
watch.Stop();
Console.WriteLine("统计结果为:" + total);
Console.WriteLine("计算时间为:" + watch.Elapsed);
}
 
static void GenerateByteArray()
{
var r = new Random(987);
for (int i = 0; i < values.Length; i++)
{
values[i] = (byte)r.Next(10);
}
}
}
 

如果把统计工作同时交给多个线程,是否可以把统计时间省下来呢?

 

□ 同时使用多个线程

现在要对"统计字节数组大小"这个任务进行均分、切分。首先面临的问题是:按什么标准均分?

--这个完全是靠个人喜好,可以让2个线程,3个线程......来处理。在这里,就根据CPU的数量来均分,因为CPU的数量可以通过Environment.ProcessorCount获得。

 

面临的第二问题是:均分什么?

--比如有4个CPU
--那可以把任务分成4个线程同时处理
--把字节数组的长度均分,比如字节数组的长度是1000,均分成4段,每段长度为250
--把字节数组的大小分成4个放一个数组里,即[sum1, sum2, sum3, sum4],所有的元素加起来就是字节数组的总大小

 
class Program
{
static byte[] values = new byte[500000000];
 
//分段统计的大小放该数组,比如分成4等份,[10000,10005,10008,10009]
private static long[] partialSum;
 
//把values数组长度均等分,比如长度1000,分成4粉,那partialSize就是250
private static int partialSize;
 
static void Main(string[] args)
{
//根据CPU的数量确定数组的长度
partialSum = new long[Environment.ProcessorCount];
 
//根据CPU的数量确定数组长度均等分
partialSize = values.Length/Environment.ProcessorCount;
 
GenerateByteArray();
Console.WriteLine("正在统计字节数");
Stopwatch watch = new Stopwatch();
watch.Start();
long total = 0;
for (int i = 0; i < values.Length; i++)
{
total += values[i];
}
watch.Stop();
Console.WriteLine("统计结果为:" + total);
Console.WriteLine("计算时间为:" + watch.Elapsed);
Console.WriteLine();
 
watch.Reset();
watch.Start();
Thread[] threads = new Thread[Environment.ProcessorCount];
for (int i = 0; i < Environment.ProcessorCount; i++)
{
threads[i] = new Thread(SumPartial);
threads[i].Start(i);
}
 
//保证一个线程结束再执行下一个线程
for (int i = 0; i < Environment.ProcessorCount; i++)
{
threads[i].Join();
}
 
//统计总大小
long total2 = 0;
for (int i = 0; i < Environment.ProcessorCount; i++)
{
total2 += partialSum[i];
}
watch.Stop();
Console.WriteLine("使用分段线程统计的大小:" + total2);
Console.WriteLine("计算时间为:" + watch.Elapsed);
}
 
/// 
/// 分段统计字节数组的大小
/// 
/// 比如有4个CPU,partialNumber可能的值是0, 1, 2, 3
static void SumPartial(object partialNumber)
{
long sum = 0;
int partialNumberAsInt = (int)partialNumber;
int baseIndex = partialNumberAsInt * partialSize;
for (int i = baseIndex; i < baseIndex + partialSize; i++)
{
sum += values[i];
}
partialSum[partialNumberAsInt] = sum;
}
 
/// 
/// 创建字节数组
/// 
static void GenerateByteArray()
{
var r = new Random(987);
for (int i = 0; i < values.Length; i++)
{
values[i] = (byte)r.Next(10);
}
}
}
 
 

以上,统计字节数组大小的方式倒不是最重要的,线程部分才是重点:

○ 有几个CPU,就有几个线程
○ 线程的实例方法Start可以传递object类型的参数
○ 线程的实例方法Join,用来保证执行完上一个线程再执行下一个线程

在这里,使用多线程同时处理一个任务,效率差不多提高了2.6倍!

 

总结:

○ 对于一个比较耗时的任务可以同时交给多个线程处理
○ 线程的实例方法Join保证执行完上一个线程再执行下一个线程

 

 

线程系列包括:

转载于:https://www.cnblogs.com/darrenji/p/3980252.html

你可能感兴趣的文章
C# Stream 和 byte[] 之间的转换
查看>>
OMG: daily scrum nine
查看>>
redis与spring结合错误情况
查看>>
第六章 字节码执行方式--解释执行和JIT
查看>>
字符串方法title()、istitle()
查看>>
yield语句
查看>>
查看linux系统中占用cpu最高的语句
查看>>
[洛谷P1738]洛谷的文件夹
查看>>
ubuntu server设置时区和更新时间
查看>>
【京东咚咚架构演进】-- 好文收藏
查看>>
【HTML】网页中如何让DIV在网页滚动到特定位置时出现
查看>>
文件序列化
查看>>
jQuery之end()和pushStack()
查看>>
Bootstrap--响应式导航条布局
查看>>
Learning Python 009 dict(字典)和 set
查看>>
JavaScript中随着鼠标拖拽而移动的块
查看>>
HDU 1021 一道水题
查看>>
The operation couldn’t be completed. (LaunchServicesError error 0.)
查看>>
php每天一题:strlen()与mb_strlen()的作用分别是什么
查看>>
工作中收集JSCRIPT代码之(下拉框篇)
查看>>