多線程簡介 1.Process與Thread 程式本身是指定和數據的有序集合,其本身沒有任何運行的含義,是一個靜態的概念。 而進程則是執行程式中的一次執行過程,是一個動態的概念。是系統能夠資源分配的單位。 通常在一個進程里,可以包含若幹個線程,當然一個進程至少有一個線程,不然沒有存在的意義。 線程是 ...
多線程簡介
1.Process與Thread
- 程式本身是指定和數據的有序集合,其本身沒有任何運行的含義,是一個靜態的概念。
- 而進程則是執行程式中的一次執行過程,是一個動態的概念。是系統能夠資源分配的單位。
- 通常在一個進程里,可以包含若幹個線程,當然一個進程至少有一個線程,不然沒有存在的意義。
- 線程是CPU調度和執行的單位,線程是獨立的執行路徑
註:很多的多線程是模擬出來的,真正的多線程是指有多個cpu,即多核,如伺服器。如果模擬出來的多線程,即在一個cpu的情況下,在同一個時間點,cpu只能執行一個代碼,因為切換的很快,所有就有同時執行的錯覺
- 在程式運行時,及時沒有為自己創建線程,後臺也會有多個線程,如主線程,gc線程等。
- main()稱為主線程,為系統的入口,用於執行整個程式
- 在一個線程中,如果開闢了多個線程,線程的運行由調度器安排調度,調度器是與操作系統緊密相關的,先後順序是不能人為的干預的。
- 對同一份資源操作時,會存在資源搶奪的問題,需要加入併發控制。
- 線程會帶來額外的開銷,如cpu調度時間,併發控制開銷
- 每個線程在自己的工作記憶體交互,記憶體控制不當會造成數據不一致
- 對現在的程式來說至少需要兩個線程,一個是執行main方法的主線程,一個垃圾回收(gc)線程.
2.線程的創建
我們現在一共有三種方式創建線程,分別是繼承Threa類,
2.1通過繼承Thread類創建
//創建方式一:繼承Thread類,重寫run()方法,調用start開啟線程
package com.thread;
public class ThreadTest01 {
public static void main(String[] args) {
MyThread01 myThread01 = new MyThread01();
myThread01.start();
//start()方法的作用是:啟動一個分支線程,在JVM中開闢一個新的棧空間,這段代碼在任務完成之後,瞬間就結束了
//這段代碼的任務只是為了開啟一個新的棧空間,只要新的棧空間開出來,start ()方法就結束了,線程就啟動成功了
//啟動成功的線程會自動調用run方法,並且run方法在分支線的棧底部(壓線)
//run()方法在分支棧的棧底部,man方法在主棧的棧底部,run和main是平級的
//muThread01.run;不會啟動線程,不會分配新的分支線(這就是單線程)
for (int i = 0; i < 100; i++) {
System.out.println("主線程"+i);
}
}
static class MyThread01 extends Thread{
@Override
public void run() {
//編寫程式,這段程式運行在分支線程中
for (int i = 0; i < 100; i++) {
System.out.println("分支線程"+i);
}
}
}
輸出:因為輸出較多,我們截取一部分,可以看出,是交替執行的。
主線程8
分支線程68
分支線程69
主線程9
分支線程70
分支線程71
分支線程72
分支線程73
分支線程74
分支線程75
分支線程76
主線程10
分支線程77
主線程11
分支線程78
主線程12
分支線程79
主線程13
分支線程80
主線程14
分支線程81
主線程15
主線程16
分支線程82
主線程17
線程開啟不一定立即執行,是由cpu安排調度的
2.2編寫一個類實現java.lang.Runnable介面
代碼示例:
public class ThreadTest03 {
public static void main(String[] args) {
//創建線程對象
Thread t = new Thread(new MyRunnable());
//啟動線程
t.start();
for (int i = 0; i < 100; i++) {
System.out.println("主線程"+i);
}
}
//這並不是一個線程類,是一個可運行的類,還不是一個線程
static class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("分支線程"+i);
}
}
}
}
部分輸出結果:
分支線程31
分支線程32
主線程45
主線程46
主線程47
主線程48
主線程49
主線程50
主線程51
主線程52
主線程53
主線程54
主線程55
主線程56
主線程57
主線程58
主線程59
主線程60
主線程61
分支線程33
分支線程34
分支線程35
分支線程36
分支線程37
分支線程38
分支線程39
註:第二種方式實現介面比較常見,因為一個類實現了皆可以,還可以去繼承其它的類,更加靈活!
3.多線程併發
-
進程與進程之間的記憶體獨立不共用
-
在一個進程中,線程和線程的堆記憶體和方法區記憶體共用。但是棧記憶體獨立,一個線程一個棧
假設啟動十個線程,就會有十個棧空間,每個棧與每個棧之間,互不幹擾,各自執行,這就是多線程併發
本文來自博客園,作者:星餘明,轉載請註明原文鏈接:https://www.cnblogs.com/lingstar/p/16529082.html