學習線程時,最令我印象深入的就是那種不肯定性、沒有保障性,各個線程的運行徹底是以不可預料的方式和速度推動,有的一個程序運行了N次,其結果差別性很大。一步一步來,首先讓咱們看看什麼是線程。
線程是彼此互相獨立的、能獨立運行的子任務,而且每一個線程都有本身的調用棧。所謂的多任務是經過週期性地將CPU時間片切換到不一樣的子任務,雖然從微觀上看來,單核的CPU上同時只運行一個子任務,可是從宏觀來看,每一個子任務彷佛是同時連續運行的。
在java中,線程指兩個不一樣的內容:一是java.lang.Thread類的一個對象;另外也能夠指線程的執行。線程對象和其餘的對象同樣,在堆上建立、運行、死亡。但不一樣之處是線程的執行是一個輕量級的進程,有它本身的調用棧。
能夠這樣想,每一個調用棧都對應一個線程,每一個線程又對應一個調用棧。咱們運行java程序時有一個入口函數main()函數,它對應的線程被稱爲主線程。一個新線程一旦被建立,就產生一個新調用棧,從原主線程中脫離,也就是與主線程併發執行。
在Java中建立線程有兩種方法:使用Thread類和使用Runnable接口。在使用Runnable接口時須要創建一個Thread實例。所以,不管是經過Thread類仍是Runnable接口創建線程,都必須創建Thread類或它的子類的實例。下面看一下建立並啓動線程的例子:
Java代碼
public
class MyThread
extends Thread {
private String threadName;
public
void run() {
for (
int i = 0; i < 20; i++) {
this.currentThread().getName();
System.out.println(Thread.currentThread().getName());
if (
this.threadName.equals(
"A"))
System.out.println(
"線程" +
this.threadName +
"在計數:" + i);
else
if(
this.threadName.equals(
"B"))
System.out.println(
"--------線程" +
this.threadName +
"在計數:" + i);
}
}
public MyThread(String name) {
super(name);
this.threadName = name;
}
public MyThread() {
super();
}
public
static
void main(String args[]) {
MyThread mt1 =
new MyThread(
"A");
mt1.start();
MyThread mt2 =
new MyThread(
"B");
mt2.start();
}
}
運行結果爲:
A
B
--------線程B在計數:0
B
--------線程B在計數:1
B
--------線程B在計數:2
B
--------線程B在計數:3
B
--------線程B在計數:4
B
--------線程B在計數:5
B
--------線程B在計數:6
B
--------線程B在計數:7
B
--------線程B在計數:8
B
--------線程B在計數:9
線程A在計數:0
A
線程A在計數:1
A
線程A在計數:2
A
線程A在計數:3
A
線程A在計數:4
A
線程A在計數:5
A
線程A在計數:6
A
線程A在計數:7
A
線程A在計數:8
A
線程A在計數:9
A
線程A在計數:10
A
線程A在計數:11
A
線程A在計數:12
A
線程A在計數:13
A
B
--------線程B在計數:10
B
--------線程B在計數:11
B
--------線程B在計數:12
B
--------線程B在計數:13
B
線程A在計數:14
A
線程A在計數:15
A
線程A在計數:16
A
線程A在計數:17
A
線程A在計數:18
A
線程A在計數:19
--------線程B在計數:14
B
--------線程B在計數:15
B
--------線程B在計數:16
B
--------線程B在計數:17
B
--------線程B在計數:18
B
--------線程B在計數:19
另外一個建立線程的方式:
Java代碼
public
class RunableThread
implements Runnable {
private String threadName;
public
void run() {
for (
int i = 0; i < 100; i++) {
if (
this.threadName.equals(
"A"))
System.out.println(
"線程" +
this.threadName +
"在計數:" + i);
else
if (
this.threadName.equals(
"B"))
System.out.println(
"--------線程" +
this.threadName +
"在計數:" + i);
}
}
public
static
void main(String[] args) {
RunableThread r1 =
new RunableThread(
"A");
Thread t1 =
new Thread(r1);
RunableThread r2 =
new RunableThread(
"B");
Thread t2 =
new Thread(r2);
t1.start();
t2.start();
}
}
線程會以如下三種方式之一結束
(1) 線程到達其run()方法的末尾;
(2) 線程拋出一個未捕獲到得Exception或Error;
(3) 另外一個線程調用一個Deprecated的 stop() 方法。這個方法會引發線程的安全問題,已經不推薦使用了.因此不要調用這個方法