Re: [問題] 關於Threading

看板java作者 (沉默是金。)時間15年前 (2010/03/07 12:52), 編輯推噓2(203)
留言5則, 4人參與, 最新討論串2/2 (看更多)
※ 引述《BlackMatrix (BlackMatrix)》之銘言: : 最近教授正在教Threading, 班上的好像高中都已經學過了, 教授以超快速的速度帶過 : 一大堆東西,還好我有一些比較可靠的書本可以幫我 : 可是有一點, Threading, 書本上教得很模糊 : (Just Java 2 6e, Data Structures and Problem Solving Using Java 3e) : 我不太確定我這樣寫的對不對, 以下是某些Code: : public class Main : { : public static void main(String[] args) : { : new ThreadDemo1().start(); : System.out.println("Hello from Main!"); : System.out.println("Program is now finished"); : } : } : class ThreadDemo1 extends Thread : { : public void run() : { : try : { : sleep(500); : } : catch (InterruptedException ex) : { : Logger.getLogger(ThreadDemo1.class.getName()).log(Level.SEVERE, : null, ex); : } : System.out.println("ThreadDemo1 saying howdy!"); : } : } : 我有個問題就是說: : 如果跑這個code, 會變成 : Hello From Main : Program is now finsihed : ThreadDemo1 saying Howdy : 會變成這樣是因為Thread把Main跟ThreadDemo1各分成一個Thread,然後因為Main的Thread : 先跑完,在跑ThreadDemo1的Thread才會這樣嗎? Thread其實不保證 ThreadDemo1 的instance 跟 main那一個先跑完, (不過main會等旗下所有新增的thread跑完才會結束(Terminal)。) 之所以會前兩行是在前面,跟demo1 有sleep 500 比較有關, sleep 500 的期間讓main印出那兩行是綽綽有餘. : 另一個問題是, 如果我要找一個素數(Prime Number) : public class Main : { : public static void main(String[] args) : { : for (int i = 0; i<1000; i++) : { : new ThreadDemo2(i).start(); : } : } : } : class ThreadDemo2 extends Thread : { : int number; : ThreadDemo2(int primeTest) : { : number = primeTest; : } : public void run() : { : boolean isPrime = true; : for (int i = 2; i <= Math.sqrt(number)&& isPrime; i++) : { : if (number%1 == 0) : { : isPrime=false; : } : } : if(isPrime) : { : System.out.println(number+ " is a prime"); : } : } : } : 如果利用這個Code跑的話, 他出來的數字都不是一個一個一個i=1,i=2,i=3下去 : 請問是因為Thread是分成i=1,i=2,i=3同時在跑的嗎? : 如果我有225個processes, 那一次性可以算225個prime number? : 如果我用sleep(在Demo 1)用這樣的寫法呢? 對,但實際上cpu還是會看狀況依序分資源給各 process , 所以並不是 process 越多就越powerfull。 (有需要多Thread又兼顧效率的話,ThreadPool是個好選擇。) 就算用sleep 在這個例子因為大家都sleep 500 , 加上一開始先後觸發start的順序幾乎是瞬間, 恐怕也沒辦法達成順序執行的目的。 : 最後一個大問題, : public class Main : { : public static void main(String[] args) : { : new ThreadDemo5(5).start(); : new ThreadDemo6(6).start(); : } : } : class Dummy : { : static Integer stuff = new Integer(0); : } : class Dummy2 : { : static Integer stuff = new Integer(0); : } : class ThreadDemo5 extends Thread : { : int id; : ThreadDemo5(int n) : { : id = n; : } : public void run() : { : for (int i=0; i<500; i++) : { : synchronized (Dummy2.stuff) : { : yield(); : synchronized (Dummy.stuff) : { : System.out.print(id); : } : } : } : } : } : class ThreadDemo6 extends Thread : { : int id; : ThreadDemo6(int n) : { : id = n; : } : public void run() : { : for (int i=0; i<500; i++) : { : synchronized (Dummy2.stuff) : { : yield(); : synchronized (Dummy.stuff) : { : System.out.print(id); : } : } : } : } : } : Dummy的作用是... : synchronized的原意是要只讓一個Thread跑的意思嗎? : 可是為什麼跑這段Code的時候會... : 變成5555556666666555555666666, 不是應該是555555556666666嗎? : yield的作用是把Thread暫停一下讓其他Thread跑, 為什麼如果我把yield拿掉的話 : 結果都不是持續性的55555555666666666而是55665555566655555666段開的呢? : 謝謝大家的幫忙 : 以下是Code: : http://nopaste.csie.org/670f3 synchronized 是同一時間只有一個Thread可以通過 也就是有一個Thread在用這個元素的時候, 另一個Thread不能用,但是並不保證會讓哪一個Thread一直佔用。 你就把他想成兩台賽車。 平常是兩條跑道各自前進,所以就都會交錯, 碰到 synchronized 的時候就好像過一條只有單行道的門, 一定要有一方先過去另一方才能過去, 但是也不保證另一方一定會先跑好幾圈跑到終點才讓另一方過去, 只要另一方有機會就會過去。 至於 yield 就好像進場保養一樣,他只是休息一下, 也沒有保證一定會讓另一台車超他車才會繼續前進, 反正他覺得保養夠了就會繼續前進。(某個角度上跟Thread.sleep 有點像) 以你給的數據來講 , 連續那幾個5跟那幾個6就是他進場保養了比較久, 拿掉之後就是沒有進場保養的數據。 -- I am a person, and I am always thinking . Thinking in love , Thinking in life , Thinking in why , Thinking in worth. I can't believe any of what , I am just thinking then thinking , but worst of all , most of mine is thinking not actioning... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.133.218.161 ※ 編輯: TonyQ 來自: 220.133.218.161 (03/07 12:54)

03/07 12:57, , 1F
謝謝TonyQ大大講解,我有點比較明白Threading的用意了
03/07 12:57, 1F

03/07 16:05, , 2F
補充一下,non-daemon thread 才會 prevent JVM 停機。
03/07 16:05, 2F

03/07 16:37, , 3F
樓上是說我第一段回文關於新thread跑完才會讓main結束的部份
03/07 16:37, 3F

03/07 18:10, , 4F
是的,我是針對第一段(...)部分,我前一推文沒講明
03/07 18:10, 4F

03/08 15:08, , 5F
推文完才發現TonyQ已經回了落落長的一篇XD
03/08 15:08, 5F
文章代碼(AID): #1Bap3-UN (java)
討論串 (同標題文章)
文章代碼(AID): #1Bap3-UN (java)