程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java多線程實現方式,java多線程實現

java多線程實現方式,java多線程實現

編輯:JAVA綜合教程

java多線程實現方式,java多線程實現


一、什麼是線程?

    線程:程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位。

    多線程:單個程序中同時運行多個線程完成不同的工作,稱為多線程。

    特點:

    1)輕量級的進程,程序運行流中可執行的最小單元,線程不擁有系統資源,多個線程共享進程擁有的資源。

    2)一個線程可以創建另外一個線程,多個線程可以並發執行。

    3)多個線程在系統運行中搶占資源,會出現間斷性,我們看到的是並行執行,其實在有先後順序的。

    4)一個進程至少包含一個線程,即主線程。

 

二、線程有哪些狀態?

 

 

    線程具有:新建,就緒,運行,阻塞,終止五種狀態。

    ①新建:線程被創建,沒有執行任何方法,如,Thread th = new Thread()。

    ②就緒:當調用線程的start方法時,就會觸發線程狀態變更為就緒態,等待cpu來調用。處於就緒態的線程才會被cpu調度,單cpu不是立即執行它。

    ③運行:當cpu發起對此線程調用時,它就進入了運行態。

    ④阻塞:當線程由於某種原因,不再擁有cpu使用權,它就會被阻塞。

        阻塞有以下幾種情況:

     1)sleep(long mills):參數為毫秒數,使線程在指定的時間內進入阻塞,時間一過,進入就緒態。

     2)suspend() 和 resume():suspend會讓線程掛起,必須執行resume進行線程的恢復。

     3)yield():與sleep()類似,但是不能由用戶指定暫停多長時間,只能出讓機會給同優先級的線程,且不進入阻塞。如同排隊,前面的人和後面的人交換位置,但是還處在隊伍中。

     4)wait() 和 notify():wait() 使線程進入阻塞狀態,有兩種形式,一種指定毫秒數,另一種無參。前者可通過notify()喚起或者超過指定時間自動恢復;後者必須通過notify()喚起。

    5)同步阻塞:等待同步鎖資源。多線程競爭同一個資源時,只能一個線程獲得鎖,其它的線程要等待。

    ⑤終止:線程執行完畢,或者出現異常,線程結束。

     

三、如何創建線程?

    java線程的實現方式有三種:繼承Thread類、實現Runnable接口,使用Callable和FutureTask(可以有返回值)

1、通過集成Thread類,覆寫run()方法

class MyThread extends Thread {

@Override

public void run() {

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

System.out.println(Thread.currentThread().getName() + " " + i);

}

}

}

 

public class ThreadDemo {

public static void main(String[] args) {

System.out.println(Thread.currentThread().getName());

MyThread th1 = new MyThread();

MyThread th2 = new MyThread();

th1.start();

th2.start();

}

}

輸出:main

Thread-1 0

Thread-0 0

Thread-1 1

Thread-1 2

......

    線程要實現的邏輯寫在run方法中,通過執行線程的start()方法,使線程進入就緒狀態,等待CPU分配資源。

    可以看到兩個線程並行執行,且隨機獲得CPU。

 

2、試過實現Runnable接口,實現run()方法

class MyThread implements Runnable {

@Override

public void run() {

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

System.out.println(Thread.currentThread().getName() + " " + i);

}

}

}

 

public class ThreadDemo {

public static void main(String[] args) {

System.out.println(Thread.currentThread().getName());

MyThread th = new MyThread();

Thread t1 = new Thread(th);

Thread t2 = new Thread(th);

t1.start();

t2.start();

}

}

輸出:main

Thread-0 0

Thread-0 1

Thread-1 0

Thread-0 2

......

通過將MyThread實例傳入Thread構造方法實例化Thread,調用Thread的start方法,啟動線程。

 

ps:繼承Thread和實現Runnable接口有什麼區別呢?

1:前者為單繼承,有局限性,但接口的方式可以實現多個。

2:後者可以實現資源共享。

多線程編程中,強烈建議使用Runnable

 

3、使用Callable和Future接口創建線程。

    具體是創建Callable接口的實現類,並實現clall()方法。

    並使用FutureTask類來包裝Callable實現類的對象,且以此FutureTask對象作為Thread對象的target來創建線程。

 

class MyCallable implements Callable<Integer> {

@Override

public Integer call() throws Exception {

return 1;

}

}

 

public class ThreadDemo {

public static void main(String[] args)  {

Callable<Integer> myCallable = new MyCallable();//實例化MyCallable

FutureTask<Integer> ft = new FutureTask<>(myCallable);//通FutureTask包裝

 

Thread thread = new Thread(ft);//將FutureTask傳入Thread構造,實例化線程

thread.start();//線程啟動

 

Integer result = ft.get();//獲取返回值

System.out.println(result);

 

}

}

1)實現Callable接口中的call()方法,這個是線程要執行的邏輯。

2)FutureTask的get()方法會一直阻塞,直到call()方法執行完畢取到返回值。

 


關注老姜談技術,微信號:helojava,或者掃描下面二維碼。


每日一帖,技術雞湯。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved