1. 多線程實現最核心的機制
一個程序在其執行過程中, 可以產生多個線程, 形成多條執行線索。,每條線程,有產生、存在和消亡的過程,並且獨立完成各自的功能,互不干擾。
多線程程序運行只佔用一個CPU,使用“時間片輪轉法”運行程序,如圖:
2. Java中的多線程實現
Java應用程序總是從主類的main()方法開始執行,如果main()方法中創建了其它線程,在主線程和其它線程之間輪流切換執行,保證每個線程都有機會使用CPU,直到程序中所有線程都結束, Java應用程序才結束。
在Java中,每個線程的狀態有以下四種:
線程狀態切換時調用的方法在圖中已標示出來,這些對線程進行操作的方法都在java.lang.Thread
類中,這個類是專門用來創建線程和對線程進行操作的類,還包括特殊的 run( )方法。
在Java中,創建線程有兩種方法:
- 繼承Thread類
- 實現Runnable接口
線程創建方法1—繼承Thread類
具體定義方法如下:
- ① 定義類的時候繼承Thread類;
- ② 重寫 Thread 類的 run() 方法;
- ③ 準備在線程中完成的工作放在run() 方法實現;
定義之後創建對象,然後通過該對象調用start()方法即可啓動線程。
示例代碼如下:
import java.lang.Thread;
class MyThread extends Thread {
String name;
int count;
MyThread(String name, int count){
this.name = name;
this.count = count;
}
public void run() {
for(int i = 0; i < count;i++) {
System.out.println(name + ":" + i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//創建線程
MyThread myThread1 = new MyThread("A",5);
MyThread myThread2 = new MyThread("B",5);
//啓動線程
myThread1.run();
myThread2.run();
}
}
運行效果如下:
線程創建方法2—實現Runnable接口
具體定義方法如下:
- ① 定義類的時候實現Runnable接口;
- ② 重寫接口中的 run() 方法;
- ③ 準備在線程中完成的工作放在run() 方法實現;
定義之後創建對象,然後通過該對象調用start()方法即可啓動線程。
示例代碼如下:
import java.lang.Thread;
class MyTestThread implements Runnable{
String name;
int count;
MyTestThread(String name, int count){
this.name = name;
this.count = count;
}
public void run() {
for(int i = 0; i < count;i++) {
System.out.println(name + ":" + i);
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
//創建線程
MyTestThread myThread1 = new MyTestThread("A",3);
MyTestThread myThread2 = new MyTestThread("B",3);
//啓動線程
myThread1.run();
myThread2.run();
}
}
運行效果如下:
3. 多線程之間的同步和互斥
在多線程程序中,可能會有兩個甚至更多的線程試圖同時訪問一個有限的資源,在編寫程序時必須對這種潛在資源衝突進行預防。
爲了解決這種衝突,在線程使用一個資源時爲其加鎖即可,訪問資源的第一個線程爲其加上鎖以後,其他線程便不能再使用那個資源,除非被解鎖。
加鎖的方法非常簡單,只需要對於訪問某個關鍵共享資源的所有方法,加上synchronized
修飾符即可,比如:
synchronized void f();
加鎖之後,其它線程想使用這個方法時就必須等待,直到線程A 使用完該方法,除非線程A主動讓出CPU資源。
示例代碼如下:
import java.lang.Thread;
class MySyncThread implements Runnable{
String name;
int count;
/* 所有該類對象共享資源 */
private static int number = 100;
MySyncThread(String name, int count){
this.name = name;
this.count = count;
}
public void run() {
int temp;
for(int i = 0; i < count;i++) {
temp = sub();
System.out.println(name + ":number = " + number);
//主動掛起,讓出CPU
try {
Thread.sleep(2000);
}
catch (Exception e) {
System.out.println("發生異常啦!");
}
}
}
/* 上鎖 */
public synchronized int sub() {
number--;
return number;
}
}
public class ThreadTest3 {
public static void main(String[] args) {
//創建線程
MySyncThread myThread1 = new MySyncThread("A",3);
MySyncThread myThread2 = new MySyncThread("B",3);
//啓動線程
myThread1.run();
myThread2.run();
}
}
運行效果如下: