進程是程序的一次動態執行過程,它經歷了從代碼加載、執行到執行完畢的一個完整過程,這個過程也是進程自己從產生、發展到最終消亡的過程。多進程操做系統能同時運行多個進程(程序),因爲 CPU 具有分時機制,因此每一個進程都能循環得到本身的 CPU 時間片。因爲 CPU 執行速度很是快,使得全部程序好象是在「同時」運行同樣。java
線程是比進程更小的執行單位,線程是進程內部單一的一個順序控制流。多線程
所謂多線程是指一個進程在執行過程當中能夠產生多個線程,這些線程能夠同時存在、同時運行,造成多條執行線索。一個進程可能包含了多個同時執行的線程。併發
多線程是實現併發機制的一種有效手段。進程和線程同樣,都是實現併發的一個基本單位。線程和進程的主要差異體如今如下兩個方面:ide
( 1)、一樣做爲基本的執行單元,線程是劃分得比進程更小的執行單位。測試
( 2)、每一個進程都有一段專用的內存區域。與此相反,線程卻共享內存單元(包括代碼和數據),經過共享的內存單元來實現數據交換、實時通訊與必要的同步操做。spa
多線程和多進程的區別?操作系統
最本質的區別就是,每一個進程用於一整套的變量,而線程則是共享數據。並且,與進程相比較,線程更「輕量級」,建立、撤銷一個線程比啓動一個新進程的開銷要小不少。
命令行
未使用多線程線程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
Test {
public
static
void
main(String[] args) {
new
TestThraed().run();
for
(
int
i =
0
; i <
10
; i++) {
System.out.println(
"main方法在運行"
+i);
}
}
}
class
TestThraed {
public
void
run() {
for
(
int
i =
0
; i <
10
; i++) {
System.out.println(
"TestThread在運行"
+i);
}
}
}
|
上面這段代碼是沒有使用多線程的狀況,程序輸出結果是按順序執行的,也就是先調用TestThread中的run方法,而後再執行main中的for循環代理
TestThread在運行0
........省略部分..........
TestThread在運行9
main方法在運行0
........省略部分..........
main方法在運行9
當使用多線程的時候
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
class
Test {
public
static
void
main(String[] args) {
/**
* 開啓一個新線程並啓動它【不要直接調用run方法】
* 若是直接調用Thread.run()方法,只會執行同一線程【main線程】的任務,而不會啓動新線程。
*/
new
TestThraed().start();
for
(
int
i =
0
; i <
10
; i++) {
System.out.println(
"main方法在運行"
+i);
}
}
}
class
TestThraed
extends
Thread{
@Override
public
void
run() {
for
(
int
i =
0
; i <
10
; i++) {
System.out.println(
"TestThread在運行"
+i);
}
}
}
|
使用了多線程後,程序的結果是交叉執行的。也就是在main線程中開闢了一個新的線程。因爲main自己也佔用一條線程,實際上在命令行中運行 java 命令時,就啓動了一個 JVM 的進程,默認狀況下此進程會產生兩個線程:一個是 main()方法線程,另一個就是垃圾回收( GC)線程。因此這裏是兩條線程main線程和new TestThread().start()線程。兩個線程同時交替運行着。
結果以下:
main方法在運行0
TestThread在運行0
main方法在運行1
TestThread在運行1
........省略部分..........
main方法在運行8
main方法在運行9
TestThread在運行8
TestThread在運行9
要想使某個程序是多線程運行的,能夠將其變爲多線程的程序。多線程程序的run方法中才是該多線程須要執行分解任務的邏輯。任意一個類都是能夠變成多線程程序的。
建立線程的方式有以下兩種:
1.實現Runnable接口,該接口中只有一個抽象的run方法 public abstract void run();
2.繼承Thread類,其實Thread類內部也是實現了Runnable接口。只不過內部封裝了對線程的一些經常使用操做。
3.1 實現Runnable接口的方式建立線程:實現Runnable接口,重寫run方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//實現Runnable接口的方式來建立線程
public
class
Programmer
implements
Runnable{
@Override
public
void
run() {
for
(
int
i =
0
; i <
100
; i++) {
System.out.println(
"第"
+i+
"次"
);
}
}
}
//測試多線程
public
class
TestProgrammer {
public
static
void
main(String[] args) {
//1.建立真實角色
Programmer pro =
new
Programmer();
//2.建立代理角色+真實角色的引用
Thread proxy =
new
Thread(pro);
//3.調用start方法,啓動線程
proxy.start();
for
(
int
i =
0
; i <
100
; i++) {
System.out.println(
"QQ"
);
}
}
}
|
3.2 繼承Thread類方式來建立線程:繼承Thread類,重寫run方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//繼承Thread類的方式來建立線程
public
class
Rabbit
extends
Thread {
@Override
public
void
run() {
for
(
int
i =
0
; i <
10
; i++) {
System.out.println(
"兔子跑了"
+i+
"步"
);
}
}
}
//測試多線程
public
class
TestThread {
public
static
void
main(String[] args) {
Rabbit rabbit =
new
Rabbit();
rabbit.start();
//不要調用run方法
}
}
|
警告:啓動線程時,不要直接調用Thread或者Runnable接口的run方法,直接調用run方法只會執行同一個線程中的任務。而不會啓動新線程。
應該調用Thread.start()方法。這個方法將建立一個執行run方法的新線程。
一、線程和進程的區別?
進程是一個程序的動態執行過程,它會在CPU給分配的一塊內存中執行一段程序【一我的在一個房間裏執行一個程序】
線程只是比進程更小的執行單位,它是進程內部單一的一個順序控制流。
多線程則是把一個任務進行分解,一個程序在內存執行的時候產生多個線程,多線程共享某塊數據。讓多個線程來執行該一個程序【多我的在一個房間執行一個程序】
一個進程中可能包括多個線程,一個線程只能屬於一個進程。
二、線程的建立方式?
繼承Thread類或者實現Runnable接口
三、繼承Thread類仍是實現Runnable接口?
推薦實現Runnable接口,避免單繼承問題
四、線程的啓動?
啓動一個線程須要調用start()方法,不要直接調用run方法。run方法只會執行同一個線程中的任務而不會去開啓新線程。start方法是建立一個執行run方法的新線程。