问题描述
多线程的好处让效率提高很多倍,但是在某些情况下要求操作同一个方法的时候要求有间隔,这个间隔当然是毫秒级别的否则多线程的意义就体现不出来,本问题就是怎么让多线程中每个线程间隔毫秒执行同一个方法,测试代码如下:privatevoidbtnTest_Click(objectsender,EventArgse){TestManyThreadtest=newTestManyThread();test.Start();}
主要代码如下classTestManyThread{privatestaticDateTimelastOperyTime=DateTime.Now;privatestaticobjectlockTime=newobject();publicstaticDateTimeLastOperyTime{get{lock(lockTime){returnTestManyThread.lastOperyTime;}}set{lock(lockTime){TestManyThread.lastOperyTime=value;}}}publicvoidStart(){for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();}}///<summary>///多个线程做同一件事件但是要求每一个线程做同一件事件之间有毫秒级的间隔///</summary>privatevoidDoSomeThing(){TimeSpansp=DateTime.Now.Subtract(LastOperyTime);intintervalTime=100;//2个线程之间的间隔时间毫秒if(sp.TotalMilliseconds<intervalTime){System.Threading.Thread.Sleep(intervalTime);}LastOperyTime=DateTime.Now;stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);}}
解决方案
解决方案二:
这个是输出的结果不符合要求.因为后面的毫秒没有间隔100以上,
解决方案三:
3296,33963496.....3996当然顺序不用控制,可以是329634963396只要最近2个线程的间的操作时间间隔大于100毫秒就行
解决方案四:
我也想学习这个,帮你顶上
解决方案五:
classTestManyThread{privatestaticDateTimelastOperyTime=DateTime.Now;privatestaticobjectlockTime=newobject();publicvoidStart(){for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();}}///<summary>///多个线程做同一件事件但是要求每一个线程做同一件事件之间有毫秒级的间隔///</summary>privatevoidDoSomeThing(){//...其他耗时操作//...//同步操作lock(lockTime){intintervalTime=100;//2个线程之间的间隔时间毫秒Thread.Sleep(Math.Max(0,intervalTime-(DateTime.Now-lastOperyTime).Milliseconds));stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);lastOperyTime=DateTime.Now;}}}
解决方案六:
如果你只是要求100毫秒以上,并不是非常准确的100毫秒限制,那么可以用这个System.Threading.Timertimer=newSystem.Threading.Timer(newTimerCallback(doNext),null,0,100);
解决方案七:
你的Thread.Sleep完全放错了地方。一个“DoSomething”怎么管起线程的事情来了?你这个程序就是“摆着毛病而故意胡乱找理由”。你既然一齐“Thread.Start”,然后来纠结它们“应该间隔100毫秒再启动”,这不是自相矛盾嘛。故意找到一个无关的代码去纠结一个很浅显的需求,是为了什么呢?
解决方案八:
解决方案九:
http://www.baidu.com看下
解决方案十:
乱用线程
解决方案十一:
如果说要错开启动时间,一般人都会直截了当地写for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;Thread.Sleep(i*100);th.Start();}
之类的代码。这里的问题是lz的习惯性的逻辑方式,似乎缺乏理科学生基本的素质训练。你的多个帖子都有类似的明显的故意“偷换逻辑”的习惯。
解决方案十二:
/*撸主,你应该是启动每个线程的时候,Sleep多少毫秒!而不是DoSomeThing做Sleep,DoSomeThing进行Sleep,是每个线程执行某个动作的时候,动作Sleep多少毫米!打个比方:10个人每个1分钟吃一个苹果(DoSomeThing)!你在DoSomeThing做Sleep,相当于苹果不是一口气吃完,而是吃的过程中暂停一下在继续吃*/for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();//Sleep一下}
解决方案十三:
线程调度的顺序是操作系统决定的不是你所能决定的了的你最多也只能设置线程的优先级就算你在启用线程的时候Thread.sleep(100)也有可能这个误差低于100毫秒因为操作系统完全可以在某些情况下将这个任务延迟执行反而去执行你后开启线程的任务。
解决方案十四:
windows不是实时操作系统,系统的定时器也没有这么高的精度,如果真要高精度的定时器,你可以看看windows核心编程
解决方案十五:
千万不要使用Thread.Sleep,用个计时器进行计时,使用AutoManualReset做线程间的同步。
解决方案:
可以使用一个AutoResetEvent来控制,初始为有信号,线程进入方法前等待这个信号.退出方法后SLEEP一段时间后设为不信号,就可以让下一个线程进入运行状态.
解决方案:
学习了
解决方案:
引用2楼QQ81867376的回复:
3296,33963496.....3996当然顺序不用控制,可以是329634963396只要最近2个线程的间的操作时间间隔大于100毫秒就行
是这个道理哦
解决方案:
期待有好的方法。
解决方案:
解决方案:
学些了,我也有类似的问题!
解决方案:
我国产剧怎么拍都没话说,把人人影视查封就说明心虚害怕
解决方案:
引用6楼sp1234的回复:
你的Thread.Sleep完全放错了地方。一个“DoSomething”怎么管起线程的事情来了?你这个程序就是“摆着毛病而故意胡乱找理由”。你既然一齐“Thread.Start”,然后来纠结它们“应该间隔100毫秒再启动”,这不是自相矛盾嘛。故意找到一个无关的代码去纠结一个很浅显的需求,是为了什么呢?
引用10楼sp1234的回复:
如果说要错开启动时间,一般人都会直截了当地写for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;Thread.Sleep(i*100);th.Start();}之类的代码。这里的问题是lz的习惯性的逻辑方式,似乎缺乏理科学生基本的素质训练。你的多个帖子都有类似的明显的故意“偷换逻辑”的习惯。
楼主,你应该听取这个大神的意见。
解决方案:
这种可行
解决方案:
classProgram{staticintdur=200;staticstringtm="";staticvoidMain(string[]args){for(inti=0;i<10;i++){vartd=newThread(newThreadStart(()=>{lock(tm){if(tm==""){Thread.Sleep(dur);}else{vart=DateTime.Now.Subtract(DateTime.Parse(tm));Thread.Sleep(dur-(int)t.TotalSeconds);}};DoSomeThing();}));td.Start();}Console.Read();}privatestaticvoidDoSomeThing(){tm=DateTime.Now.ToShortTimeString();stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);Thread.Sleep(5000);}}
解决方案:
解决方案:
好久没来CSDN论坛了。。。,看到这个贴子,就回一下吧楼主,上面已有人说了你的逻辑不严密了,所以我就再说这个了,就给你一点简单的建议,想要控制线程之间严格执行一段代码或是函数,要将代码函数或里面的某一小段Lock起来,让某一时刻只能有一个线程进入!这样就可以所有访问该代码的线程都受到管控,否则你就会出现结果根本不是你想要的
解决方案:
引用4楼Forty2的回复:
classTestManyThread{privatestaticDateTimelastOperyTime=DateTime.Now;privatestaticobjectlockTime=newobject();publicvoidStart(){for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();}}///<summary>///多个线程做同一件事件但是要求每一个线程做同一件事件之间有毫秒级的间隔///</summary>privatevoidDoSomeThing(){//...其他耗时操作//...//同步操作lock(lockTime){intintervalTime=100;//2个线程之间的间隔时间毫秒Thread.Sleep(Math.Max(0,intervalTime-(DateTime.Now-lastOperyTime).Milliseconds));stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);lastOperyTime=DateTime.Now;}}}
最开始就这些,测试还是一样.
解决方案:
引用6楼sp1234的回复:
你的Thread.Sleep完全放错了地方。一个“DoSomething”怎么管起线程的事情来了?你这个程序就是“摆着毛病而故意胡乱找理由”。你既然一齐“Thread.Start”,然后来纠结它们“应该间隔100毫秒再启动”,这不是自相矛盾嘛。故意找到一个无关的代码去纠结一个很浅显的需求,是为了什么呢?
对于你的教育放心我不是百分百的吸收,因为你不清楚别人的需求在这就开始教育人.线程启动的时候为什么要停止,你想过没有,另外这样简单的别人想不到?还是说下的我需求,10个线程开始工作,每个线程都要解析网页内容,仅仅是在提交的时候间隔不能低于500毫秒,解析很花时间,每个一个停止100毫秒浪费时间,仅仅在提交的时候需要间隔一下,明白了?????所以不要说别人偷换概念,什么逻辑什么...你的帖子的见过比较多,为什么总是在这个方面教育人呢,写出代码能说明问题,其次才是你这道理
解决方案:
使用Timer调用放在线程中的程序,Timer毫秒级启动,计数确定执行次数使用AutoResetEvent让线程阻塞等待上一个线程方法执行完成
解决方案:
用临界资源每个进入临界资源的线程,记录下离开临界资源时的时间,然后下个进入临界资源的线程,根据当前时间和上个线程离开时间的时间差,补足100ms的差距即可!!!!
解决方案:
不知道你是不是这个意思usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceConsoleApplication2{classProgram{staticvoidMain(string[]args){mydo();Console.ReadLine();}staticvoidmydo(){Action<string>action=(str)=>{Thread.Sleep(100);stringinfo=string.Format("do{0}:线程ID:{1},执行时间:{2}",str,Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);};Task.Factory.StartNew(()=>action("1")).ContinueWith(antecendent=>action("2")).ContinueWith(antecendent=>action("3")).ContinueWith(antecendent=>action("4")).ContinueWith(antecendent=>action("5")).ContinueWith(antecendent=>action("6")).ContinueWith(antecendent=>action("7")).ContinueWith(antecendent=>action("8")).ContinueWith(antecendent=>action("9")).ContinueWith(antecendent=>action("10")).Wait();}}}
结果do1:线程ID:,执行时间:2015-04-24-23:56:04:1356do2:线程ID:,执行时间:2015-04-24-23:56:04:2406do3:线程ID:,执行时间:2015-04-24-23:56:04:3417do4:线程ID:,执行时间:2015-04-24-23:56:04:4428do5:线程ID:,执行时间:2015-04-24-23:56:04:5438do6:线程ID:,执行时间:2015-04-24-23:56:04:6459do7:线程ID:,执行时间:2015-04-24-23:56:04:7470do8:线程ID:,执行时间:2015-04-24-23:56:04:8491do9:线程ID:,执行时间:2015-04-24-23:56:04:9501do10:线程ID:,执行时间:2015-04-24-23:56:05:0522
解决方案:
使用AutoResetEvent让线程阻塞等待上一个线程方法执行完
解决方案:
你需要高精度定时器。Linux下叫做RealTimeClock、简称RTC,可以精确到CPU滴答。Windows下用QueryPerformanceFrequency+QueryPerformanceCounter可以精确到ms级
解决方案:
1.使用API计时器.2.用计时器来开新线程.
解决方案:
留言,学习。
解决方案:
多线程同步,你需要加locklock之后,你可以在被调用的函数体里面做逻辑判断是否需要延迟执行
解决方案:
这就好比,有个厕所堵了,前一个人上完厕所之后,后一个人必须等2分钟才能再上,否则就冒水了如果你多线程不做同步,那么相当于所有人互相都不认识,自己去判断别人是否上过了,那不现实,判断不了,互相没有沟通你需要有个看门的老大爷,定时往里面放人,有人了就不许进,间隔少于2分钟也不许进
解决方案:
这个可以吗?for(inti=0;i<10;i++){newThread(()=>{Trace.WriteLine(string.Format("Name:{0}Now:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss.ffff")));}){Name=i.ToString(),ApartmentState=ApartmentState.MTA,IsBackground=true}.Start();DateTimenow=DateTime.Now;TimeSpants=newTimeSpan(100*10000);SpinWait.SpinUntil(()=>{Thread.SpinWait(10);returnDateTime.Now-now>ts;});}
解决方案:
收藏学习一下,感谢各位大神!
解决方案:
学习了,很有用
解决方案:
没见过这样的用法。思路有问题~~线程可以同步
解决方案:
http://kb.cnblogs.com/page/42533/讲的很好
解决方案:
我是来学习的五一快乐
解决方案:
这个有问题,咋还置顶了。。。。。。
解决方案:
有点用多线程来做单线程的事的赶脚
解决方案:
向大神学习,留个记号
解决方案:
问题在于DataTime.Now的精度,最小精度16.5ms看到你的数据,有几个线程时间显示一样了么!你可以单独打印Data.Now.毫秒就可以看到效果了,不要打印所有时间
解决方案:
该回复于2015-09-30 23:53:14被版主删除
解决方案:
除非你做个锁,要么没办法
解决方案:
我不明白的是为什么操作同一个方法而且中间可以有数百毫秒这么长时间的间隔,还要分成多个线程来操作。。要不要吃点屎冷静一下再来写程序啊?