文章詳情頁(yè)
菜鳥(niǎo)初學(xué)Java的備忘錄(八)
瀏覽:45日期:2024-06-25 14:42:23
內(nèi)容: 我在22號(hào)的筆記中不是有一個(gè)疑問(wèn)嗎?為什么我編的程序沒(méi)有不同步的現(xiàn)象產(chǎn)生呢,我把它發(fā)到csdn上去了,現(xiàn)在我已經(jīng)基本解決這個(gè)問(wèn)題了,下面是論壇的回復(fù)紀(jì)錄摘要回復(fù)人:bluesmile979(笑著) ( ) 信譽(yù):100 2003-01-22 21:08:00 得分:0 說(shuō)說(shuō)我的看法,我認(rèn)為最大的問(wèn)題在于多線程,看了你的代碼,好像只有兩個(gè)線成了。而例子中應(yīng)該是比較多的線程,多個(gè)線程競(jìng)爭(zhēng)時(shí)間片,被打斷的幾率自然就大得多了。就算你加了循環(huán),由于機(jī)器的運(yùn)算速度,仍然沒(méi)有多個(gè)線程競(jìng)爭(zhēng)那么現(xiàn)象明顯。不知道各位以為如何?;貜?fù)人:xm4014(forrest) ( ) 信譽(yù):100 2003-01-22 22:07:00 得分:0 to bluesmile979(笑著) 我也曾經(jīng)想到過(guò)是否因?yàn)榫€程太少而導(dǎo)致,但是我將Think in java的例程中的兩個(gè)參數(shù)都設(shè)為1來(lái)運(yùn)行,那么最后也就和我寫(xiě)的程序一樣,只有兩個(gè)線程,結(jié)果照樣有不同步.這又怎么解釋呢回復(fù)人:tianfeichen(側(cè)耳傾聽(tīng)) ( ) 信譽(yù):110 2003-01-22 23:57:00 得分:0 線程的安排畢竟是隨機(jī)的,很少會(huì)有不同步的出現(xiàn),次數(shù)少了不容易發(fā)現(xiàn)。我常用的方法是,先讓無(wú)限循環(huán)開(kāi)始,循環(huán)的時(shí)候也不要求輸出什么的,只加上一個(gè)停止的條件,比如:if (counter1 != counter2){ System.out.println(counter1 + ' ,' + counter2) System.exit(0);}剩下的就是等了,一般十幾秒甚至幾秒就出結(jié)果了,可以發(fā)現(xiàn)記數(shù)已經(jīng)到幾十萬(wàn)或者幾百萬(wàn)了。如果同時(shí)開(kāi)了5個(gè)線程,等了一分鐘,我就算是它同步了。我的方法可能不太科學(xué),不過(guò)效果挺好?;貜?fù)人: xm4014(forrest) ( ) 信譽(yù):100 2003-01-23 11:44:00 得分:0 可以幫我調(diào)試一下嗎?為什么我按照你的方法卻始終沒(méi)有得到結(jié)果呢?將下面的代碼直接拷貝就可以了,程序名為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); }} ///:~另外,根據(jù)你的意思,我的程序是沒(méi)有問(wèn)題的,只是線程少了,不同步很難產(chǎn)生,要等到counter增加到很大數(shù)目的時(shí)候才有可能,對(duì)嗎?回復(fù)人: hey_you(Hey) ( ) 信譽(yù):100 2003-01-23 13:27:00 得分:0 我是這樣想的:不同步而發(fā)生沖突是一種可能性,而sychronize是讓這種可能性為0。你沒(méi)有1發(fā)現(xiàn)不同步,并不能證明永遠(yuǎn)都不會(huì)發(fā)生不同步的情況,那只是一個(gè)時(shí)間問(wèn)題。系統(tǒng)對(duì)線程的調(diào)度受了環(huán)境的影響,要是你機(jī)器上同時(shí)還跑了很多程序,可能情況就不同了。回復(fù)人: xm4014(forrest) ( ) 信譽(yù):100 2003-01-23 15:56:00 得分:0 呵呵,我用tianfeichen(側(cè)耳傾聽(tīng))的方法運(yùn)行的程序,也就是我上面貼的代碼居然有結(jié)果了,counter1= 217327,counter2=217356,還真想差的不少。但是時(shí)間上絕不是一兩分鐘那么簡(jiǎn)單,至少過(guò)了兩個(gè)小時(shí),可能真是我和他的運(yùn)行環(huán)境的不同造成的.正如hey_you(Hey)所說(shuō),只是一個(gè)時(shí)間問(wèn)題.希望其它人能給出更多的看法,如果覺(jué)得沒(méi)必要再討論下去,那我就接貼.回復(fù)人: bluesmile979(笑著) ( ) 信譽(yù):100 2003-01-23 16:38:00 得分:0 我考,一兩個(gè)小時(shí)你也能堅(jiān)持,服了。我認(rèn)為問(wèn)題結(jié)果也就兩點(diǎn)了。一個(gè)就是我認(rèn)為的線程數(shù)量另一個(gè)就是你認(rèn)為的setText會(huì)有比較多的處理,占用比較多的資源。兩種情況都會(huì)影響到這個(gè)問(wèn)題的出現(xiàn)幾率:)樓主宰總結(jié)一下吧,呵呵?;貜?fù)人: linliangyi(藍(lán)山咖啡) ( ) 信譽(yù):100 2003-01-23 17:10:00 得分:0 sleep(500)占用的時(shí)間勝過(guò)for(5000)的時(shí)間,因此線程在sleep中被切換的概率遠(yuǎn)勝于在for中被中斷的概率!!(回頭去看我的程序就知道了)事實(shí)上,兩個(gè)變量從不相等變?yōu)橄嗟龋钦f(shuō)明了不同步!!順便說(shuō)一下關(guān)于swing和awt控件在線程中操作時(shí),比如setText,常造成很多意外樓主可以看看相關(guān)的書(shū)籍!!回復(fù)人: xm4014(forrest) ( ) 信譽(yù):100 2003-01-24 14:25:00 得分:0 我將各位的觀點(diǎn)綜合起來(lái)總結(jié)一下:首先要肯定的是,假如不使用synchronized關(guān)鍵字來(lái)定義同步方法或者定義同步塊,那么,發(fā)生不同步的可能是絕對(duì)存在的,反過(guò)來(lái)說(shuō),synchronized就是讓這種可能性為0.在第一種情況下,發(fā)生不同步的可能雖然存在,但是它的幾率受到以下幾個(gè)方面因素的影響1.在不同的操作系統(tǒng)及運(yùn)行環(huán)境下,捕捉到不同步的幾率可能就不一樣,或者說(shuō)等待的時(shí)間可能就有長(zhǎng)有短2.程序中線程數(shù)目的多寡,如果線程太少,那么這種不同步就難于捕捉到,可能需要等待很長(zhǎng)的時(shí)間3.代碼本身的影響.比如使用awt類中涉及到GUI的方法,可能就會(huì)占用較多的資源,造成很多意外,那么發(fā)生沖突的可能性就大得多4.線程是由操作系統(tǒng)隨機(jī)分配的,本來(lái)就存在著不確定性,這種不確定性也會(huì)影響最后的結(jié)果不知道是否正確,大家還有什么補(bǔ)充呢?明天正式結(jié)帖不過(guò)說(shuō)實(shí)話,我有點(diǎn)搞不懂,為什么最后的結(jié)果,counter1(217327)和counter2(217356)會(huì)相差那么多呢.按照我的程序,即便watcher線程插到兩個(gè)自加的語(yǔ)句中間來(lái),檢測(cè)到的這兩個(gè)計(jì)數(shù)器之間的差異頂多也就是1啊.出現(xiàn)這么大的差異,只可能是某一個(gè)計(jì)數(shù)器的自加語(yǔ)句有好多次在根本沒(méi)有運(yùn)行的情況下就被強(qiáng)行中斷了.這就太恐怖了!雖然有其它線程的存在會(huì)干擾當(dāng)前線程,但是也不至于讓當(dāng)前線程語(yǔ)句不運(yùn)行吧,最多也就是等等再運(yùn)行啊?我有點(diǎn)糊涂了,操作系統(tǒng)沒(méi)學(xué)好,如果大家不嫌麻煩,清幫我解釋一下吧結(jié)果現(xiàn)在又有新的問(wèn)題,我想又要等到明天才有答案吧但我們今天可以解決另一個(gè)涉及到synchronized的問(wèn)題.這是我在論壇上看到的一個(gè)貼子.正是因?yàn)槲医鉀Q不了,我才認(rèn)為有必要回頭來(lái)好好研究線程和同步等內(nèi)容的.問(wèn)題如下: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)//括號(hào)里的b是什么意思,起什么作用? { try { System.out.println('Waiting for b to complete...'); b.wait();//這一句是什么意思,究竟讓誰(shuí)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
標(biāo)簽:
Java
相關(guān)文章:
排行榜
