新聞中心
1. 線程是什么
操作系統(tǒng)支持多個應用程序并發(fā)執(zhí)行,每個應用程序至少對應一個進程 ,彼此之間的操作和數據不受干擾,彼此通信一般采用管道通信、消息隊列、共享內存等方式。當一個進程需要磁盤IO的時候,CPU就切換到另外的進程,提高了CPU利用率。

創(chuàng)新互聯堅持“要么做到,要么別承諾”的工作理念,服務領域包括:網站設計、成都網站制作、企業(yè)官網、英文網站、手機端網站、網站推廣等服務,滿足客戶于互聯網時代的丹徒網站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯網解決方案。努力成為您成熟可靠的網絡建設合作伙伴!
有了進程,為什么還要線程?因為進程的成本太高了。
啟動新的進程必須分配獨立的內存空間,建立數據表維護它的代碼段、堆棧段和數據段,這是昂貴的多任務工作方式。線程可以看作輕量化的進程。線程之間使用相同的地址空間,切換線程的時間遠小于切換進程的時間。
進程是資源分配的最小單位,而線程是CPU調度的最小單位。每一個進程中至少有一個線程,同一進程的所有線程共享該進程的所有資源,多個線程可以完成多個不同的任務,也就是我們常說的并發(fā)多線程。
2. 怎樣創(chuàng)建線程
創(chuàng)建線程常用的有四種方式,分別是:
- 繼承Thread類
- 實現Runnable接口
- 實現Callable接口
- 使用線程池創(chuàng)建
分別看一下怎么具體怎么使用代碼創(chuàng)建的?
2.1 繼承Thread類
public class ThreadDemo {
public static void main(String[] args){
Thread thread = new MyThread();
thread.start(); // 啟動線程
}
}
class MyThread extends Thread {
@Override
public void run(){
System.out.println("關注公眾號:一燈架構");
}
}輸出結果:
關注公眾號:一燈架構
start方法用來啟動線程,只能被調用一次。
run方法是線程的核心方法,業(yè)務邏輯都寫在run方法中。
2.2 實現Runnable接口
public class ThreadDemo {
public static void main(String[] args){
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable, "線程1");
Thread thread2 = new Thread(myRunnable, "線程2");
thread1.start(); // 啟動線程1
thread2.start(); // 啟動線程2
}
}
class MyRunnable implements Runnable {
private int count = 5;
@Override
public void run(){
while (count > 0) {
System.out.println(Thread.currentThread().getName()
+ ",關注公眾號:一燈架構," + count--);
}
}
}輸出結果:
線程2,關注公眾號:一燈架構,4
線程1,關注公眾號:一燈架構,5
線程1,關注公眾號:一燈架構,2
線程1,關注公眾號:一燈架構,1
線程2,關注公眾號:一燈架構,3
需要把Runnable實例放到Thread類中,才能執(zhí)行,Thread對象才是真正的線程對象。
使用實現Runnable接口創(chuàng)建線程方式,相比繼承Thread類創(chuàng)建線程,優(yōu)點是:
- 實現的方式沒有類的單繼承性的局限性
- 實現的方式更適合來處理多個線程有共享數據的情況
2.3 實現Callable接口
public class ThreadTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
FutureTask futureTask = new FutureTask(myCallable);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(futureTask.get());
}
}
class MyCallable implements Callable {
@Override
public String call() throws Exception {
return "關注公眾號:一燈架構";
}
} 輸出結果:
關注公眾號:一燈架構
實現Callable接口的線程實例對象,配合FutureTask使用,可以接收返回值。
2.4 使用線程池創(chuàng)建
public class ThreadDemo {
public static void main(String[] args){
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(() -> System.out.println("關注公眾號:一燈架構"));
}
}輸出結果:
關注公眾號:一燈架構
使用線程池創(chuàng)建線程是工作開發(fā)中最常用的方式,優(yōu)點是:
- 線程池幫忙管理對象的創(chuàng)建與銷毀,減輕開發(fā)者工作量
- 線程池幫忙管理任務的調用,資源的創(chuàng)建與分配
- 復用線程和對象,提高使用效率
3. 線程的狀態(tài)
線程共有6種狀態(tài),分別是NEW(初始化)、RUNNABLE(可運行)、WAITING(等待)、TIMED_WAITING(超時等待)、BLOCKED(阻塞)、TERMINATED(終止)。
- NEW(初始化)
表示創(chuàng)建線程對象之后,還沒有調用start方法。
- RUNNABLE(可運行)
表示調用start方法之后,等待CPU調度。為了便于理解,通常又把RUNNABLE分別RUNNING(運行中)和READY(就緒)。處在RUNNING(運行中)狀態(tài)的線程可以調用yield方法,讓出CPU時間片,然后跟其他處于READY(就緒)一起等待被調度。
- WAITING(等待)
處于RUNNABLE狀態(tài)的線程調用wait方法之后,就處于等待狀態(tài),需要其他線程顯示地喚醒。
- TIMED_WAITING(超時等待)
處于RUNNABLE狀態(tài)的線程調用wait(long)方法之后,就處于等待狀態(tài),需要其他線程顯示地喚醒。
- BLOCKED(阻塞)
等待進入synchronized方法/代碼塊,處于阻塞狀態(tài)。
- TERMINATED(終止)
表示線程已經執(zhí)行結束。
4. 線程常用方法
說一下線程有哪些常用的方法。
|
方法定義 |
含義 |
使用方式 |
|
public synchronized void start() {……} |
啟動線程 |
MyThread myThread = new MyThread(); myThread.start(); |
|
public static native Thread currentThread(); |
獲取當前線程實例對象 |
Thread thread = Thread.currentThread(); |
|
public static native void yield(); |
讓出CPU時間片 |
Thread.yield(); |
|
public static native void sleep(long millis); |
睡眠指定時間 |
Thread.sleep(1L); |
|
public void interrupt() {……} |
中斷線程 |
MyThread myThread = new MyThread(); myThread.interrupt(); |
|
public static boolean interrupted() {……} |
判斷線程是否已中斷 |
MyThread myThread = new MyThread(); boolean interrupted = myThread.isInterrupted(); |
|
public final native boolean isAlive(); |
判斷線程是否是存活狀態(tài) |
MyThread myThread = new MyThread(); boolean alive = myThread.isAlive(); |
|
public final String getName() {……} |
獲取線程名稱 |
MyThread myThread = new MyThread(); String name = myThread.getName(); |
|
public State getState() {……} |
獲取線程狀態(tài) |
MyThread myThread = new MyThread(); Thread.State state = myThread.getState(); |
|
public long getId() {……} |
獲取線程ID |
MyThread myThread = new MyThread(); long id = myThread.getId(); |
|
public final void join() {……} |
等待其他線程執(zhí)行完再執(zhí)行 |
MyThread myThread = new MyThread(); myThread.join(); |
網站欄目:夯實Java基礎,一篇文章全解析線程問題
本文來源:http://m.fisionsoft.com.cn/article/dpjoeoh.html


咨詢
建站咨詢
