Java多線程

Java多線程

1. 進程與線程

  • 線程:程序中單獨的控制流
    線程本身依靠程序進行運行
    線程是程序中的順序控制流,只能使用分配給程序的資源和環(huán)境

  • 進程:執(zhí)行中的程序
    一個進程可以包含一個或多個線程
    一個進程至少包含一個線程

  • 單線程:程序中只存在一個線程,實際上主方法就是一個主線程

  • 多線程:在一個程序中運行多個任務(wù)
    目的是更好地使用CPU資源

2. 線程的實現(xiàn)

  • 繼承Thread
    java.lang包中定義, 繼承Thread類必須重寫run()方法

  • 實現(xiàn)Runnable接口

3. 線程的狀態(tài)

  • 創(chuàng)建狀態(tài): 準備好了一個多線程的對象
  • 就緒狀態(tài): 調(diào)用了start()方法, 等待CPU進行調(diào)度
  • 運行狀態(tài): 執(zhí)行run()方法
  • 阻塞狀態(tài): 暫時停止執(zhí)行, 可能將資源交給其它線程使用
  • 終止狀態(tài): 線程銷毀

4. 線程的常用方法

  • 取得線程名稱: getName()

  • 取得當(dāng)前線程對象: currentThread()

  • 判斷線程是否啟動: isAlive()

  • 線程的強制執(zhí)行: join()
    手動強制執(zhí)行另一個線程

  • 線程的休眠: sleep()
    常用. 讀入?yún)?shù)毫秒.

  • 線程的禮讓: yield()

class RunnableDemo implements Runnable {

    private String name;

    public RunnableDemo(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println(name + ":" + i);
            if (i == 10) {
                System.out.println("線程" + name + "禮讓");
                Thread.yield();
            }
        }
    }
}

public class ThreadDemo {

    public static void main(String[] args) {
        RunnableDemo r1 = new RunnableDemo("A");
        RunnableDemo r2 = new RunnableDemo("B");
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
    }
}

// 執(zhí)行結(jié)果
B:0
A:0
B:1
A:1
A:2
A:3
A:4
A:5
A:6
A:7
A:8
A:9
A:10
線程A禮讓
B:2
A:11
B:3
A:12
A:13
A:14
A:15
A:16
B:4
A:17
B:5
B:6
B:7
B:8
A:18
B:9
B:10
線程B禮讓
A:19
...

5. 線程的優(yōu)先級

優(yōu)先級設(shè)置:

  • 1--MIN_PRIORITY

  • 5--NORM_PRIORITY(默認)

  • 10--MAX_PRIORITY

class RunnableDemo implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + ":" + i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadDemo {

    public static void main(String[] args) {
        Thread t1 = new Thread(new RunnableDemo(), "A");
        Thread t2 = new Thread(new RunnableDemo(), "B");
        Thread t3 = new Thread(new RunnableDemo(), "C");
        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.NORM_PRIORITY);
        t3.setPriority(Thread.MAX_PRIORITY);
        t1.start();
        t2.start();
        t3.start();
    }
}

// 執(zhí)行結(jié)果
B:0
A:0
C:0
B:1
A:1
C:1
B:2
A:2
C:2
B:3
C:3
A:3
C:4
A:4
B:4
// 從第4次往后C才獲得優(yōu)先執(zhí)行, 所以設(shè)置優(yōu)先級并不能保證線程的執(zhí)行順序.

6. 同步

資源共享的時候需要使用同步.

  1. 同步代碼塊
synchronized(同步對象){
    需要同步的代碼塊;
}
  1. 同步方法
synchronized void fun(){
    
}
  1. 示例:
class RunnableDemo implements Runnable {

    private int ticket = 5;

    @Override
    public void run() {

        for (int i = 0; i < 10; i++) {
            synchronized (this) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("stcket: " + ticket--);
                }
            }
        }
    }
}

public class ThreadDemo {

    public static void main(String[] args) {
        RunnableDemo r = new RunnableDemo();
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);
        t1.start();
        t2.start();
        t3.start();
    }
}

// 執(zhí)行結(jié)果
// 若不加synchronized
stcket: 4
stcket: 5
stcket: 3
stcket: 2
stcket: 1
stcket: 0
stcket: -1
// 加上synchronized
stcket: 5
stcket: 4
stcket: 3
stcket: 2
stcket: 1

// 采用同步方法,結(jié)果一樣
class RunnableDemo implements Runnable {

    private int ticket = 5;

    @Override
    public void run() {

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

    public synchronized void fun() {
        if (ticket > 0) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("stcket: " + ticket--);
        }
    }
}

7. 線程的生命周期

cycle.png

注:sleep和wait的區(qū)別:

  • sleepThread類的方法,waitObject類中定義的方法.
  • Thread.sleep不會導(dǎo)致鎖行為的改變, 如果當(dāng)前線程是擁有鎖的, 那么Thread.sleep不會讓線程釋放鎖.
  • Thread.sleepObject.wait都會暫停當(dāng)前的線程. OS會將執(zhí)行時間分配給其它線程. 區(qū)別是, 調(diào)用wait后, 需要別的線程執(zhí)行notify/notifyAll才能夠重新獲得CPU執(zhí)行時間.
8. Thread類重要方法總結(jié)
編號 方法 說明
1 public void start() 使該線程開始執(zhí)行;Java 虛擬機調(diào)用該線程的 run 方法。
2 public void run() 如果該線程是使用獨立的 Runnable 運行對象構(gòu)造的,則調(diào)用該 Runnable 對象的 run 方法;否則,該方法不執(zhí)行任何操作并返回。
3 public final void setName(String name) 改變線程名稱,使之與參數(shù) name 相同。
4 public final void setPriority(int priority) 更改線程的優(yōu)先級。
5 public final void setDaemon(boolean on) 將該線程標記為守護線程或用戶線程。
6 public final void join(long millisec) 等待該線程終止的時間最長為 millis 毫秒。
7 public void interrupt() 中斷線程。
8 public final boolean isAlive() 測試線程是否處于活動狀態(tài)。
9 public static void yield() 暫停當(dāng)前正在執(zhí)行的線程對象,并執(zhí)行其他線程。
10 public static void sleep(long millisec) 在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計時器和調(diào)度程序精度和準確性的影響。
11 public static Thread currentThread() 返回對當(dāng)前正在執(zhí)行的線程對象的引用。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,591評論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,105評論 1 18
  • 該文章轉(zhuǎn)自:http://blog.csdn.net/evankaka/article/details/44153...
    加來依藍閱讀 7,464評論 3 87
  • 寫在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的,為什么轉(zhuǎn)載兩個字加“”呢?因為這絕不是簡單的復(fù)制粘貼,我花了五六個小...
    SmartSean閱讀 4,935評論 12 45
  • 1 街道旁酒綠燈紅, 街道上車水馬龍。 獨自走在花叢, 為何會這么冷? 心還在無力地顫抖。 因為…… 疼。 2 你...
    秋之夏風(fēng)閱讀 228評論 0 0

友情鏈接更多精彩內(nèi)容