作者TonyQ (沉默是金。)
看板java
标题Re: [问题] 关於Threading
时间Sun Mar 7 12:52:12 2010
※ 引述《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)
1F:推 BlackMatrix:谢谢TonyQ大大讲解,我有点比较明白Threading的用意了 03/07 12:57
2F:→ sbrhsieh:补充一下,non-daemon thread 才会 prevent JVM 停机。 03/07 16:05
3F:→ TonyQ:楼上是说我第一段回文关於新thread跑完才会让main结束的部份 03/07 16:37
4F:→ sbrhsieh:是的,我是针对第一段(...)部分,我前一推文没讲明 03/07 18:10
5F:推 DavyBlue:推文完才发现TonyQ已经回了落落长的一篇XD 03/08 15:08