java多線程學習筆記

前言:對于java多線程的資料數不勝數,我們這里只是在學習后簡單地總結一下并給出一些小例子,本文適合java初學者。不過在開始之前,我們還是要弄明白一個問題——線程和進程有什么區別?其實一個進程是一個獨立的運行環境,它可以被看作一個程序或者一個應用,而線程是在進程中執行的一個任務,線程是進程的子集,一個進程可以有很多線程,每條線程并行執行不同的任務。不同的進程使用不同的內存空間,而所有的線程共享一片相同的內存空間。別把它和棧內存搞混,每個線程都擁有單獨的棧內存用來存儲本地數據。

1.創建線程的方法

創建線程方法一:繼承Thread類,使用子類創建

編寫繼承Thread子類MyThread

//MyThread.java

public class MyThread extends Thread{

? ?private String name;

? ?public MyThread(String name){

? ? ? this.name= name;

? ?}

? ?//繼承Thread類必須重寫run()方法

? ?@Override

? ?public void run() {

? ? ? System.out.println("name:" + name + "子線程ID:"

? ? ? + Thread.currentThread().getId());

? ?}

}

在main方法里面編寫代碼:

System.out.println("主線程ID:"+ Thread.currentThread().getId());

//創建多個子線程

for(int i = 0; i < 5; i++){

? ?String threadName = "Thread" + (i + 1);

? ?MyThread thread = new MyThread(threadName);

? ?thread.start();

}

//注:直接調用Thread的run方法,并不會在新的線程上執行,而是跟普通方法調用一樣,在當前線程上執行

MyThread threadSpec = new MyThread("ThreadSpec"); ? //特例

threadSpec.run();

運行結果

說明:啟動線程是通過start()方法,而不是調用run()方法,在線程獲取cpu執行時間的時候會自動調用run()方法。

創建線程方法二:實現Runnable接口,在Runnable上定義任務,然后將Runnable交由Thread執行

編寫實現Runnable的實現類MyRunnable

//MyRunnable.java

public class MyRunnable implements Runnable {

? ?public MyRunnable(){}

? ?//實現Runnable接口必須重寫其run方法

? ?@Override

? ?public void run() {

? ? ? System.out.println("子線程ID:"+ Thread.currentThread().getId());

? ?}

}

在main方法里面編寫代碼:

MyRunnable runnable = new MyRunnable();

Thread thread = new Thread(runnable);

thread.start();

運行結果

說明:和方法一對比,方法二可能有些啰嗦,但是Java只允許單繼承,如果實際情況中類需要繼承其他類,則只能選擇方法二來實現多線程。

2.使用ExecutorService、Callable、Future實現有返回結果的多線程

先編寫實現Callable的實現類MyCallable

//MyCallable.java

public class MyCallable implements Callable {

? ?private String taskIndex;

? ?MyCallable(String taskIndex){

? ? ? this.taskIndex = taskIndex;

}

? ?@Override

? ?public Object call() throws Exception {

? ? ? System.out.println(taskIndex + "號任務啟動");

? ? ? Date startDate = new Date();

? ? ? Thread.sleep(1000);

? ? ? Date endDate = new Date();

? ? ? long time = endDate.getTime() - startDate.getTime();

? ? ? System.out.println(taskIndex + "號任務終止");

? ? ? return taskIndex + "號任務返回運行結果,當前任務執行【" + time +"毫秒】";

? ?}

}

在main方法里面編寫代碼:

//使用ExecutorService、Callable、Future實現有返回結果的多線程

System.out.println("------程序開始運行-----");

Date startDate = new Date();

int taskSize = 5;

//創建一個線程池

ExecutorService pool = Executors.newFixedThreadPool(taskSize);

//創建多個有返回值的任務

List list =new ArrayList<>();

for(int i =0;i < taskSize;i++){

? ?Callable c = new MyCallable(i +"");

? ?//執行任務并獲取Future對象

? ?Future f = pool.submit(c);

? ?list.add(f);

}

//關閉線程池

pool.shutdown();

//獲取所有并發任務的運行結果

for(Future f : list){

? ?//從Future對象上獲取任務的返回值

? ?System.out.println(f.get().toString());

}

Date endDate =new Date();

System.out.println("------程序結束運行-----,程序運行了【"+ (endDate.getTime() - startDate.getTime()) +"毫秒】");

運行結果

說明:ExecutorService、Callable、Future這個對象實際上都是屬于Executor框架中的功能類。想要詳細了解Executor框架的可以訪問Java程序員必備知識-多線程框架Executor詳解。實現Callable接口,執行Callable任務后,可以獲取一個Future的對象,在該對象上調用get就可以獲取到Callable任務返回的Object了。

注:以上內容是學習java 多線程后的一個簡單的總結,如果有錯誤,請各位指出,也歡迎大家前來拍磚,灰常感謝!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容