一、多線程的概念及優勢
1.程序
程序就是一段靜態的代碼,他是程序執行的藍本。
2.進程
進程本質是程序的一次動態執行。
進程的特點: 1.動態性。 2.併發性。 3.獨立性。
3.線程
進程內部的一個執行單元。也可稱爲子進程。
說明:線程也可以理解爲程序的一條執行路徑。前面所有案例(除了GUI中,他們有內建的多線程支持)都是單線程。任何程序都是從main方法開始往下執行,只會有一條執行路徑。所以前面的案例都是單線程,這條線程是主線程 mian線程。
多線程的優勢
Ø 多線程使系統空轉時間減少,提高CPU利用率
Ø 進程間不能共享內存,但線程之間共享內存非常容易
Ø 使用多線程實現多任務併發比多進程的效率高
Ø Java語言內置多線程功能支持,簡化了Java的多線程編程
二、創建多線程的步驟及語法
★繼承Thread類,重寫run方法
◆語法:
class Test extends Thread{//繼承Thread類
public void run() {//重寫run方法
//方法體
}
}
★實現Runnable接口,實現run方法
◆語法:
class Test implements Runnable{//實現Runnabel接口
public void run() {//實現run方法
//方法體
}
}
★啓動線程:
新建的線程不會自動執行,必須通過start()方法啓動。
注意:
1.直接調用run()方法不會啓動線程,只是一次普通的方法調用。在多線程的程序中永遠不會調用run方法。
2.一條線程只能啓動一次。如果啓動多次會報IllegalThreadStateException異常。
◆啓動繼承Thread類的線程
Test t = new Test();
t.start();
◆啓動實現Runnable接口的線程
Test t = new Test();
Thread th = new Thread(t);
th.start();
★創建線程的方法對比:
|
優點 |
缺點 |
繼承Thread類 |
簡單 |
無法再繼承其他類 無法實現資源共享 |
實現Runnable接口 |
可以繼承其他類 可以實現資源共享 |
複雜 |
當線程被創建並啓動後,它既不是一啓動就進入執行狀態,也不是一直處於執行狀態,在線程的生命週期中,他要經歷新建(New)、就緒(Runnabel)、運行(Running)、阻塞(Blocked)和死亡(Dead)五種狀態。尤其是當線程啓動後,他不是一直“霸佔”CPU獨自運行,CPU需要在多條線程間切換,於是線程狀態會多次在運行、阻塞、就緒之間切換。
四、線程的同步
1.間接相互制約:A與B兩條線程,A請求打印機時,CPU將打印機分配給B,A只能等待B打印完,A才能從阻塞轉爲就緒態。
2.直接相互制約:直接相互制約主要用於進程間相互合作。
案例:
package anli;
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class RunHello extends JFrame implements Runnable{
String s = "Hello World!";
int nextX = 0;
int nextY = 0;
Color nextColor;
Font nextFont;
Random rand = new Random();
public RunHello(){
this.setSize(1366, 768);
this.setVisible(true);
}
public void paint(Graphics g){
g.setColor(nextColor);
g.setFont(nextFont);
g.drawString(s,nextX,nextY);
}
public static void main(String[] args){
RunHello rw = new RunHello();
Thread t = new Thread(rw);
t.start();
}
public void run() {
while(true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
nextX = rand.nextInt(1367);
nextY = rand.nextInt(769);
nextColor = new Color(rand.nextInt(256),rand.nextInt(256),rand.nextInt(256));
nextFont = new Font("黑體",Font.BOLD,rand.nextInt(41)+10);
this.repaint();
}
}
}