文章詳情頁
菜鳥初學Java的備忘錄(八)
瀏覽:25日期:2024-06-25 14:42:23
內容: 我在22號的筆記中不是有一個疑問嗎?為什么我編的程序沒有不同步的現象產生呢,我把它發到csdn上去了,現在我已經基本解決這個問題了,下面是論壇的回復紀錄摘要回復人:bluesmile979(笑著) ( ) 信譽:100 2003-01-22 21:08:00 得分:0 說說我的看法,我認為最大的問題在于多線程,看了你的代碼,好像只有兩個線成了。而例子中應該是比較多的線程,多個線程競爭時間片,被打斷的幾率自然就大得多了。就算你加了循環,由于機器的運算速度,仍然沒有多個線程競爭那么現象明顯。不知道各位以為如何。回復人:xm4014(forrest) ( ) 信譽:100 2003-01-22 22:07:00 得分:0 to bluesmile979(笑著) 我也曾經想到過是否因為線程太少而導致,但是我將Think in java的例程中的兩個參數都設為1來運行,那么最后也就和我寫的程序一樣,只有兩個線程,結果照樣有不同步.這又怎么解釋呢回復人:tianfeichen(側耳傾聽) ( ) 信譽:110 2003-01-22 23:57:00 得分:0 線程的安排畢竟是隨機的,很少會有不同步的出現,次數少了不容易發現。我常用的方法是,先讓無限循環開始,循環的時候也不要求輸出什么的,只加上一個停止的條件,比如:if (counter1 != counter2){ System.out.println(counter1 + ' ,' + counter2) System.exit(0);}剩下的就是等了,一般十幾秒甚至幾秒就出結果了,可以發現記數已經到幾十萬或者幾百萬了。如果同時開了5個線程,等了一分鐘,我就算是它同步了。我的方法可能不太科學,不過效果挺好?;貜腿耍?xm4014(forrest) ( ) 信譽:100 2003-01-23 11:44:00 得分:0 可以幫我調試一下嗎?為什么我按照你的方法卻始終沒有得到結果呢?將下面的代碼直接拷貝就可以了,程序名為Sharing2.java,版本是1.4.1class TwoCounter extends Thread { private int count1 = 0, count2 = 0; private boolean started=false; public void start(){ if (!started) { started=true; super.start(); } } public void run() { while (true) { count1++; count2++;// System.out.println('Count1='+count1+',Count2='+count2); try { sleep(500); } catch (InterruptedException e){System.out.println('TwoCounter.run');} } } public void synchTest() {// Sharing2.incrementAccess(); if(count1 != count2) {System.out.println(count1+','+count2); System.exit(0); } }}class Watcher extends Thread { private Sharing2 p; public Watcher(Sharing2 p) { this.p = p; start(); } public void run() { while(true) { p.s.synchTest(); try { sleep(500); } catch (InterruptedException e){System.out.println('Watcher.run');} } }}public class Sharing2 { TwoCounter s; private static int accessCount = 0; public static void incrementAccess() {// accessCount++;// System.out.println('accessCount='+accessCount); } public static void main(String[] args) { Sharing2 aaa = new Sharing2(); aaa.s=new TwoCounter(); aaa.s.start(); new Watcher(aaa); }} ///:~另外,根據你的意思,我的程序是沒有問題的,只是線程少了,不同步很難產生,要等到counter增加到很大數目的時候才有可能,對嗎?回復人: hey_you(Hey) ( ) 信譽:100 2003-01-23 13:27:00 得分:0 我是這樣想的:不同步而發生沖突是一種可能性,而sychronize是讓這種可能性為0。你沒有1發現不同步,并不能證明永遠都不會發生不同步的情況,那只是一個時間問題。系統對線程的調度受了環境的影響,要是你機器上同時還跑了很多程序,可能情況就不同了。回復人: xm4014(forrest) ( ) 信譽:100 2003-01-23 15:56:00 得分:0 呵呵,我用tianfeichen(側耳傾聽)的方法運行的程序,也就是我上面貼的代碼居然有結果了,counter1= 217327,counter2=217356,還真想差的不少。但是時間上絕不是一兩分鐘那么簡單,至少過了兩個小時,可能真是我和他的運行環境的不同造成的.正如hey_you(Hey)所說,只是一個時間問題.希望其它人能給出更多的看法,如果覺得沒必要再討論下去,那我就接貼.回復人: bluesmile979(笑著) ( ) 信譽:100 2003-01-23 16:38:00 得分:0 我考,一兩個小時你也能堅持,服了。我認為問題結果也就兩點了。一個就是我認為的線程數量另一個就是你認為的setText會有比較多的處理,占用比較多的資源。兩種情況都會影響到這個問題的出現幾率:)樓主宰總結一下吧,呵呵?;貜腿耍?linliangyi(藍山咖啡) ( ) 信譽:100 2003-01-23 17:10:00 得分:0 sleep(500)占用的時間勝過for(5000)的時間,因此線程在sleep中被切換的概率遠勝于在for中被中斷的概率!?。ɑ仡^去看我的程序就知道了)事實上,兩個變量從不相等變為相等,正是說明了不同步!!順便說一下關于swing和awt控件在線程中操作時,比如setText,常造成很多意外樓主可以看看相關的書籍??!回復人: xm4014(forrest) ( ) 信譽:100 2003-01-24 14:25:00 得分:0 我將各位的觀點綜合起來總結一下:首先要肯定的是,假如不使用synchronized關鍵字來定義同步方法或者定義同步塊,那么,發生不同步的可能是絕對存在的,反過來說,synchronized就是讓這種可能性為0.在第一種情況下,發生不同步的可能雖然存在,但是它的幾率受到以下幾個方面因素的影響1.在不同的操作系統及運行環境下,捕捉到不同步的幾率可能就不一樣,或者說等待的時間可能就有長有短2.程序中線程數目的多寡,如果線程太少,那么這種不同步就難于捕捉到,可能需要等待很長的時間3.代碼本身的影響.比如使用awt類中涉及到GUI的方法,可能就會占用較多的資源,造成很多意外,那么發生沖突的可能性就大得多4.線程是由操作系統隨機分配的,本來就存在著不確定性,這種不確定性也會影響最后的結果不知道是否正確,大家還有什么補充呢?明天正式結帖不過說實話,我有點搞不懂,為什么最后的結果,counter1(217327)和counter2(217356)會相差那么多呢.按照我的程序,即便watcher線程插到兩個自加的語句中間來,檢測到的這兩個計數器之間的差異頂多也就是1啊.出現這么大的差異,只可能是某一個計數器的自加語句有好多次在根本沒有運行的情況下就被強行中斷了.這就太恐怖了!雖然有其它線程的存在會干擾當前線程,但是也不至于讓當前線程語句不運行吧,最多也就是等等再運行啊?我有點糊涂了,操作系統沒學好,如果大家不嫌麻煩,清幫我解釋一下吧結果現在又有新的問題,我想又要等到明天才有答案吧但我們今天可以解決另一個涉及到synchronized的問題.這是我在論壇上看到的一個貼子.正是因為我解決不了,我才認為有必要回頭來好好研究線程和同步等內容的.問題如下:file://分析這段程序,并解釋一下,著重講講synchronized、wait(),notify 謝謝!class ThreadA { public static void main(String[] args) { ThreadB b=new ThreadB(); b.start(); System.out.println('b is start....'); synchronized(b)//括號里的b是什么意思,起什么作用? { try { System.out.println('Waiting for b to complete...'); b.wait();//這一句是什么意思,究竟讓誰wait? System.out.println('Completed.Now back to main thread'); }catch (InterruptedException e){} } System.out.println('Total is :'+b.total); }}class ThreadB extends Thread{ int total; public void run() { synchronized(this) { System.out.println('ThreadB is running..'); for (int i=0;i
標簽:
Java
上一條:菜鳥初學Java的備忘錄(三)下一條:菜鳥初學Java的備忘錄(九)
相關文章:
排行榜
