1、創建線程
創建線程的方式有兩種:
通過創建Thread類的子類來實現;
通過實現Runnable接口的類來實現。
class Test extends Thread {
String s;
int m, count = 0;
Test(String ss, int mm) {
s = ss;
m = mm;
}
public void run() {
try {
while (true) {
System.out.print(s);
sleep(m);
count++;
if (count >= 20)
break;
}
System.out.println(s + "finished !");
} catch (InterruptedException e) {
return;
}
}
public static void main(String args[]) {
Test threadA = new Test("A ", 2);
Test threadB = new Test("B ", 1);
threadA.start();
threadB.start();
}
}
class Test implements Runnable {
String s;
int m, count = 0;
Test(String ss, int mm) {
s = ss;
m = mm;
}
public void run() {
try {
while (true) {
System.out.print(s);
Thread.sleep(m);
count++;
if (count >= 20)
break;
}
System.out.println(s + "finished !");
} catch (InterruptedException e) {
return;
}
}
public static void main(String args[]) {
Test threadA = new Test("A ", 2);
Test threadB = new Test("B ", 1);
Thread threadC=new Thread(threadA);
Thread threadD=new Thread(threadB);
threadC.start();
threadD.start();
}
}
2、線程的優先級
線程在創建時,繼承了父類的優先級。線程創建後,可以在任何時刻調用setPriority方法改變線程的優先級。優先級爲1~10,Thread定義了其中3個常數:
MAX_PRIORITY最大優先級(值爲10);
MIN_PRIORITY最小優先級(值爲1);
NORM_PRIORITY默認優先級(值爲5)
3、線程的常用方法
start() :線程調用該方法將啓動線程,使之從新建狀態進入就緒隊列排隊,一旦輪到它來享用CPU資源時,就可以脫離創建它的線程獨立開始自己的生命週期了。
run():線程對象被調度之後所執行的操作,由系統自動調用,用戶程序不得引用。系統的Thread類中,run()方法沒有具體內容,所以用戶程序需要創建自己的Thread類的子類,並重寫run()方法來覆蓋原來的run()方法。當run方法執行完畢,線程就變成死亡狀態。
sleep(int millsecond):線程佔有CPU期間,執行sleep方法來使自己放棄CPU資源,休眠一段時間。如果線程在休眠時被打斷,JVM就拋出InterruptedException異常。因此,必須在try~catch語句塊中調用sleep方法。
isAlive():線程處於運行狀態時, isAlive()方法返回true,否則返回false。
currentThread():是Thread類中的類方法,可以用類名調用,該方法返回當前正在使用CPU資源的線程。
interrupt():用來“吵醒”休眠的線程。
例題:
有兩個線程:student和teacher,其中student準備睡一小時後再開始上課,teacher在輸出3句“上課”後,吵醒休眠的線程student.
import java.util.logging.Level;
import java.util.logging.Logger;
public class ThreadDemo {
Thread student,teacher;
class Student extends Thread {
public void run() {
try {
System.out.println("學生張三正在睡覺!");
this.sleep(1000 * 60 * 60);
} catch (InterruptedException ex) {
System.out.println("學生張三醒了!");
System.out.println("學生張三起來聽課了!");
}
}
}
class Teacher extends Thread {
public void run() {
try {
for (int i = 0; i < 3; i++) {
System.out.println("上課!");
this.sleep(500);
}
student.interrupt();
} catch (InterruptedException ex) {
Logger.getLogger(Teacher.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
ThreadDemo(){
teacher = new Teacher();
student = new Student();
}
public static void main(String args[]) {
ThreadDemo t = new ThreadDemo();
t.student.start();
t.teacher.start();
}
}
4、線程同步
Java提供了多線程機制,通過多線程的併發運行可以提高系統資源利用率,改善系統性能。但在有些情況下,一個線程必須和其他線程合作才能共同完成任務。線程可以共享內存,利用這個特點可以在線程之間傳遞信息。
在Java中,實現同步操作的方法是在共享內存變量的方法前加synchronized修飾符。在程序運行過程中,如果某一線程調用經synchronized修飾的方法,在該線程結束此方法的運行之前,其他所有線程都不能運行該方法,只有等該線程完成此方法的運行後,其他線程才能運行該方法。
在同步方法中使用wait()、notify 和notifyAll()方法:等待與通知一個線程在使用的同步方法中時,可能根據問題的需要,必須使用wait()方法使本線程等待,暫時讓出CPU的使用權,並允許其它線程使用這個同步方法。其它線程如果在使用這個同步方法時如果不需要等待,那麼它用完這個同步方法的同時,應當執行notifyAll()方法通知所有的由於使用這個同步方法而處於等待的線程結束等待。