❶ java三線程猜數問題
importjava.util.Random;
publicclassGuessNumber{
publicstaticvoidmain(String[]args){
ThreadOneone=newThreadOne();
one.start();
ThreadTwotwo=newThreadTwo("猜題線程1");
two.start();
ThreadTwothree=newThreadTwo("猜題線程2");
try{
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
three.start();
while(true){
//如果有猜對的就停止所有線程
if(two.getGuessResult().equals("猜對了")||three.getGuessResult().equals("猜對了")){
one.stop();
two.stop();
three.stop();
break;
}
}
}
}
//出題線程
classThreadOneextendsThread{
privatestaticinttheNumber;//存放要猜的數字
publicvoidrun(){
Randomrandom=newRandom();
theNumber=random.nextInt(100);
System.out.println("出題線程出的題為:"+theNumber);
}
//猜數字
publicstaticStringguessNumber(intnumber){
if(theNumber>number){
return"小了";
}elseif(theNumber<number){
return"大了";
}else{
return"猜對了";
}
}
}
//猜題線程
classThreadTwoextendsThread{
privateStringthreadName;
privateintminNum=0;
privateintmaxNum=100;
StringguessResult="";
publicThreadTwo(StringthreadName){
this.threadName=threadName;
}
publicStringgetGuessResult(){
returnguessResult;
}
publicvoidrun(){
while(true){
try{
sleep(4000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
intnowNum;
Randomrandom=newRandom();
//生成最小值和最大值之間的一個數
nowNum=minNum+random.nextInt(maxNum-minNum);
//把生成的數發到出題線程上,返回結果
guessResult=ThreadOne.guessNumber(nowNum);
if(guessResult.equals("大了")){
maxNum=nowNum;
System.out.println(threadName+"猜:"+nowNum+""+guessResult);
}elseif(guessResult.equals("小了")){
minNum=nowNum;
System.out.println(threadName+"猜:"+nowNum+""+guessResult);
}else{
System.out.println(threadName+"猜對了,結果是:"+nowNum);
}
}
}
}
❷ java中的多線程!怎麼理解
同一件事,不同的人在做就是多線程。
食堂打飯,一個人一個人打就是單線程,開N個窗口N個人同時打就是多線程
❸ 如何用Java編寫多線程
在java中要想實現多線程,有兩種手段,一種是繼續Thread類,另外一種是實現Runable介面。
對於直接繼承Thread的類來說,代碼大致框架是:
?
123456789101112 class 類名 extends Thread{ 方法1; 方法2; … public void run(){ // other code… } 屬性1; 屬性2; … }
先看一個簡單的例子:
?
/** * @author Rollen-Holt 繼承Thread類,直接調用run方法 * */class hello extends Thread { public hello() { } public hello(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "運行 " + i); } } public static void main(String[] args) { hello h1=new hello("A"); hello h2=new hello("B"); h1.run(); h2.run(); } private String name; }
【運行結果】:
A運行 0
A運行 1
A運行 2
A運行 3
A運行 4
B運行 0
B運行 1
B運行 2
B運行 3
B運行 4
我們會發現這些都是順序執行的,說明我們的調用方法不對,應該調用的是start()方法。
當我們把上面的主函數修改為如下所示的時候:
?
123456 public static void main(String[] args) { hello h1=new hello("A"); hello h2=new hello("B"); h1.start(); h2.start(); }
然後運行程序,輸出的可能的結果如下:
A運行 0
B運行 0
B運行 1
B運行 2
B運行 3
B運行 4
A運行 1
A運行 2
A運行 3
A運行 4
因為需要用到CPU的資源,所以每次的運行結果基本是都不一樣的,呵呵。
注意:雖然我們在這里調用的是start()方法,但是實際上調用的還是run()方法的主體。
那麼:為什麼我們不能直接調用run()方法呢?
我的理解是:線程的運行需要本地操作系統的支持。
如果你查看start的源代碼的時候,會發現:
?
1234567891011121314151617 public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0 || this != me) throw new IllegalThreadStateException(); group.add(this); start0(); if (stopBeforeStart) { stop0(throwableFromStop); } } private native void start0();
注意我用紅色加粗的那一條語句,說明此處調用的是start0()。並且這個這個方法用了native關鍵字,次關鍵字表示調用本地操作系統的函數。因為多線程的實現需要本地操作系統的支持。
但是start方法重復調用的話,會出現java.lang.IllegalThreadStateException異常。
通過實現Runnable介面:
大致框架是:
?
123456789101112 class 類名 implements Runnable{ 方法1; 方法2; … public void run(){ // other code… } 屬性1; 屬性2; … }
來先看一個小例子吧:
?
2930 /** * @author Rollen-Holt 實現Runnable介面 * */class hello implements Runnable { public hello() { } public hello(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "運行 " + i); } } public static void main(String[] args) { hello h1=new hello("線程A"); Thread demo= new Thread(h1); hello h2=new hello("線程B"); Thread demo1=new Thread(h2); demo.start(); demo1.start(); } private String name; }
【可能的運行結果】:
線程A運行 0
線程B運行 0
線程B運行 1
線程B運行 2
線程B運行 3
線程B運行 4
線程A運行 1
線程A運行 2
線程A運行 3
線程A運行 4
關於選擇繼承Thread還是實現Runnable介面?
其實Thread也是實現Runnable介面的:
?
12345678 class Thread implements Runnable { //… public void run() { if (target != null) { target.run(); } } }
其實Thread中的run方法調用的是Runnable介面的run方法。不知道大家發現沒有,Thread和Runnable都實現了run方法,這種操作模式其實就是代理模式。關於代理模式,我曾經寫過一個小例子呵呵,大家有興趣的話可以看一下:http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144847.html
Thread和Runnable的區別:
如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable介面的話,則很容易的實現資源共享。
?
/** * @author Rollen-Holt 繼承Thread類,不能資源共享 * */class hello extends Thread { public void run() { for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } public static void main(String[] args) { hello h1 = new hello(); hello h2 = new hello(); hello h3 = new hello(); h1.start(); h2.start(); h3.start(); } private int count = 5; }
【運行結果】:
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
大家可以想像,如果這個是一個買票系統的話,如果count表示的是車票的數量的話,說明並沒有實現資源的共享。
我們換為Runnable介面:
?
12345678910111213141516171819 /** * @author Rollen-Holt 繼承Thread類,不能資源共享 * */class hello implements Runnable { public void run() { for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } public static void main(String[] args) { hello he=new hello(); new Thread(he).start(); } private int count = 5; }
【運行結果】:
count= 5
count= 4
count= 3
count= 2
count= 1
總結一下吧:
實現Runnable介面比繼承Thread類所具有的優勢:
1):適合多個相同的程序代碼的線程去處理同一個資源
2):可以避免java中的單繼承的限制
3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。
所以,本人建議大家勁量實現介面。
?
❹ 如何使用Java編寫多線程程序
要說線程,就必須先說說進程,進程就是程序的運行時的一個實例。線程呢可以看作單獨地佔有CPU時間來執行相應的代碼的。對早期的計算機(如DOS)而言,線程既是進程,進程既是進程,因為她是單線程的。當然一個程序可以是多線程的,多線程的各個線程看上去像是並行地獨自完成各自的工作,就像一台一台計算機上運行著多個處理機一樣。在多處理機計算機上實現多線程時,它們確實可以並行工作,而且採用適當的分時策略可以大大提高程序運行的效率。但是二者還是有較大的不同的,線程是共享地址空間的,也就是說多線程可以同時讀取相同的地址空間,並且利用這個空間進行交換數據。
為什麼要使用多線程呢?學過《計算機體系結構》的人都知道。將順序執行程序和採用多線程並行執行程序相比,效率是可以大大地提高的。比如,有五個線程thread1, thread2, thread3, thread4, thread5,所耗的CPU時間分別為4,5,1,2,7。(假設CPU輪換周期為4個CPU時間,而且線程之間是彼此獨立的)順序執行需要花費19個CPU時間,而並行需要的時間肯定少於19個CPU時間,至於具體多少時間要看那些線程是可以同時執行的。這是在非常小規模的情況下,要是面對大規模的進程之間的交互的話,效率可以表現得更高。
與其他語言不一樣的是,線程的觀念在java是語言中是重要的,根深蒂固的,因為在java語言中的線程系統是java語言自建的, java中有專門的支持多線程的API庫,所以你可以以最快的速度寫一個支持線程的程序。在使用java創建線程的時候,你可以生成一個Thread類或者他的子類對象,並給這個對象發送start()消息(程序可以向任何一個派生自 Runnable 介面的類對象發送 start() 消息的),這樣一來程序會一直執行,直到run返回為止,此時該線程就死掉了。
在java語言中,線程有如下特點:
§ 在一個程序中而言,主線程的執行位置就是main。而其他線程執行的位置,程序員是可以自定義的。值得注意的是對Applet也是一樣。
§ 每個線程執行其代碼的方式都是一次順序執行的。
§ 一個線程執行其代碼是與其他線程獨立開來的。如果諸線程之間又相互協作的話,就必須採用一定的交互機制。
❺ java多線程理解
線程是系統調度中的最小單位,因為其擁有比進程更小的資源消耗,因此,在進行同類事情,需要進行互相的通訊等等事情的時候,都採用線程來進行處理。
對於只做固定的一件事情(比如:計算1+2+3+...+9999999)來說,其性能上不會比採用單線程的整體效率高,原因是,同時都是要做這么多運算,採用多線程的話,系統在進行線程調度的過程中喙浪費一些資源和時間,從而性能上下降。
那麼,多線程是否就沒有存在的意義了呢?答案當然不是的。多線程還是有存在的價值的,我們在寫輸入流輸出流,寫網路程序等等的時候,都會出現阻塞的情況,如果說,我們不使用多線程的話,從A中讀數據出來的時候,A因為沒有準備好,而整個程序阻塞了,其他的任何事情都沒法進行。如果採用多線程的話,你就不用擔心這個問題了。還舉個例子:游戲中,如果A角色和B角色採用同一個線程來處理的話,那麼,很有可能就會出現只會響應A角色的操作,而B角色就始終被佔用了的情況,這樣,玩起來肯定就沒勁了。
因此,線程是有用的,但也不是隨便亂用,亂用的話,可能造成性能的低下,它是有一點的適用范圍的,一般我認為:需要響應多個人的事情,從設計上需要考慮同時做一些事情(這些事情很多情況下可能一點關系都沒有,也有可能有一些關系的)。
使用多線程的時候,如果某些線程之間涉及到資源共享、互相通訊等等問題的時候,一定得注意線程安全的問題,根據情況看是不是需要使用synchronized關鍵字。