Thread2
五 判斷多個(gè)線程是否都結(jié)束的兩種方法
確定所有線程是否都完成了工作的方法有很多,如可以采用類似于對(duì)象計(jì)數(shù)器的方法,所謂對(duì)象計(jì)數(shù)器,就是一個(gè)對(duì)象被引用一次,這個(gè)計(jì)數(shù)器就加1,銷毀引用就減1,如果引用數(shù)為0,則垃圾搜集器就會(huì)對(duì)這些引用數(shù)為0的對(duì)象進(jìn)行回收。
方法一
? ??線程也可以采用計(jì)數(shù)器的方法,即為所有需要監(jiān)視的線程設(shè)一個(gè)線程計(jì)數(shù)器每開始一個(gè)線程,在線程執(zhí)行方法中為這個(gè)計(jì)數(shù)器加1,如果某個(gè)線程結(jié)束(在線程執(zhí)行的方法最后為這個(gè)計(jì)數(shù)器減1),為這個(gè)計(jì)數(shù)器減1,然后在開始一個(gè)線程,按著一定的時(shí)間間隔來監(jiān)視這個(gè)計(jì)數(shù)器,如是總的計(jì)數(shù)器為0,說明所有的線程都結(jié)束了。當(dāng)然,也可以不用這個(gè)監(jiān)視線程,而在每一個(gè)工作線程的最后(在為計(jì)數(shù)器減1的代碼的后面)來監(jiān)視這個(gè)計(jì)數(shù)器,也就是說,每一個(gè)工作線程在退出之前,還要負(fù)責(zé)檢測(cè)這個(gè)計(jì)數(shù)器。使用這種方法不要忘了同步這個(gè)計(jì)數(shù)器變量啊,否則會(huì)產(chǎn)生意想不到的后果。
方法二:使用Thread.join方法
join方法只有在線程結(jié)束時(shí)才繼續(xù)執(zhí)行下面的語(yǔ)句。可以對(duì)每一個(gè)線程調(diào)用它的join方法,但要注意,這個(gè)調(diào)用要在另一個(gè)線程里,而不要在主線程,否則程序會(huì)被阻塞的。
個(gè)人感覺這種方法比較好。
線程計(jì)數(shù)器方法演示:
class ThreadCounter : MyThread{private static int count = 0;private int ms;private static void increment(){lock (typeof(ThreadCounter)) // 必須同步計(jì)數(shù)器 {count++;}}private static void decrease(){lock (typeof(ThreadCounter)){count--;}}private static int getCount(){lock (typeof(ThreadCounter)){return count;}}public ThreadCounter(int ms){this.ms = ms;}override public void run(){increment();Thread.Sleep(ms);Console.WriteLine(ms.ToString()+"毫秒任務(wù)結(jié)束");decrease();if (getCount() == 0)Console.WriteLine("所有任務(wù)結(jié)束");}}ThreadCounter counter1 = new ThreadCounter(3000); ThreadCounter counter2 = new ThreadCounter(5000); ThreadCounter counter3 = new ThreadCounter(7000);counter1.start(); counter2.start(); counter3.start();? ?上面的代碼雖然在大多數(shù)的時(shí)候可以正常工作,但卻存在一個(gè)隱患,就是如果某個(gè)線程,假設(shè)是counter1,在運(yùn)行后,由于某些原因,其他的線程并未運(yùn)行,在這種情況下,在counter1運(yùn)行完后,仍然可以顯示出“所有任務(wù)結(jié)束”的提示信息,但是counter2和counter3還并未運(yùn)行。為了消除這個(gè)隱患,可以將increment方法從run中移除,將其放到ThreadCounter的構(gòu)造方法中,在這時(shí),increment方法中的lock也可以去掉了。代碼如:
public ThreadCounter(int ms){this.ms = ms;increment();}運(yùn)行上面的程序后,將顯示如圖2的結(jié)果。
?
?
使用Thread.join方法演示
private static void threadMethod(Object obj) {Thread.Sleep(Int32.Parse(obj.ToString()));Console.WriteLine(obj + "毫秒任務(wù)結(jié)束"); } private static void joinAllThread(object obj) {Thread[] threads = obj as Thread[];foreach (Thread t in threads)t.Join();Console.WriteLine("所有的線程結(jié)束"); }static void Main(string[] args) {Thread thread1 = new Thread(threadMethod);Thread thread2 = new Thread(threadMethod);Thread thread3 = new Thread(threadMethod);thread1.Start(3000);thread2.Start(5000);thread3.Start(7000);Thread joinThread = new Thread(joinAllThread);joinThread.Start(new Thread[] { thread1, thread2, thread3 });}??在運(yùn)行上面的代碼后,將會(huì)得到和圖2同樣的運(yùn)行結(jié)果。上述兩種方法都沒有線程數(shù)的限制,當(dāng)然,仍然會(huì)受到操作系統(tǒng)和硬件資源的限制。
轉(zhuǎn)載于:https://www.cnblogs.com/blosaa/archive/2013/06/04/3116382.html
總結(jié)
- 上一篇: 学习之路三十一:Varchar和NVar
- 下一篇: 纯手法打骰子怎么练的