1. 程式人生 > >java個人筆記之執行緒

java個人筆記之執行緒

簡介

基本概念

程式 - 表示存放在硬碟/磁碟上的可執行檔案。
程序 - 表示執行在記憶體中的程式。
目前主流的作業系統都支援多執行緒,但是程序都是重量級的,新建程序對cpu和記憶體的消耗都比較大,當程序到了一定數量的時候,會造成系統宕機等現象。為了減輕cpu和記憶體的消耗,提出來另外一個概念叫做執行緒。執行緒是輕量級的,是錄屬於程序內部的程式流,當新建執行緒之後會共享當前程序的資源,而不是申請新的資源,在主流的作業系統中支援執行緒的。在程序內部又可以支援多執行緒,多執行緒可以實現多行程式碼同時執行的效果,也就是並行的效果。

知識點

執行緒的並行機制

從主流的作業系統來說,cpu(單核)其實是不可分的,記憶體空間是可分的,可以將cpu的一段執行時間劃分為多個小時間片,然後經每個執行緒都分配一個小時間片,這樣的話,在一段時間內可以做成所有執行緒都執行的效果,叫做時間片輪轉。本質上來說真正的並行並不存在,而是從時間段的角度去考慮是並行的,但是從時間點的角度去考慮是序列的。

常用的構造方法和普通方法

常用的構造方法:
Thread() – 分配新的Thread物件
Thread(Runnable target) – 分配新的Thread物件
Thread(String name) – 分配新的Thread物件
常用的普通方法:
static Thread currentThread()
– 返回當前正在執行的執行緒物件的引用
long getId() – 返回該執行緒的識別符號,有系統自動生成
String getName() – 返回該執行緒的名稱
void setName(String name) – 設定該執行緒的名稱
void run() – 如果該執行緒是使用獨立的Runnable執行物件構造的,則呼叫該 Runnable物件的run方法;否則該方法不執行任何操作並返回
void start() – 使該執行緒開始執行;Java 虛擬機器呼叫該執行緒的 run 方法

執行緒建立的方式

執行緒的兩種建立方式

第一種:
繼承java.lang.Thread類, 重寫run()方法,並呼叫start()方法,其中執行main()方法的執行緒叫做主執行緒。其中新建出來的執行緒重新run()方法,並呼叫start()方法
第二種:
實現Runnable介面,重寫run()方法,並呼叫start()方法。

執行緒的兩種建立方式的注意點

1、繼承Thread類的方法相對簡單,但是無法再繼承其它的類,java支援單繼承
2、實現Runnable介面的方式相對比較複雜,但是可以再繼承其它的類
3、多執行緒之間的執行是相互獨立的,也就是並行的,但是每個執行緒內部是序列的

執行緒的狀態

執行緒中總共有五種狀態:
1、新建狀態:呼叫構造方法創建出來的執行緒的預設狀態
2、就緒狀態:建立的執行緒呼叫start()方法進入的狀態;阻塞狀態的執行緒解除阻塞進入的狀態;執行狀態的執行緒停止執行進入的狀態
3、執行狀態:正在執行的執行緒所處的狀態,需要執行緒排程器來排程;當執行緒執行完畢之後就回答了就緒狀態
4、阻塞狀態:暫時停止執行的執行緒的狀態;當執行緒執行了sleep()方法也可以進入阻塞狀態;當執行緒睡醒了回到就緒狀態
5、消亡狀態:執行緒中的所有程式碼執行完畢的狀態

例項

第一種執行緒建立的例項

建立的執行緒類:

package com.Thread;

public class Thread1 extends Thread{

    @Override
    public void run(){
        for(int i = 0; i < 10;i ++){
            System.out.println(i);
        }
    }

}       

呼叫執行緒的類:

package com.Thread;

public class TestThread {

    public static void main(String[] args){
        Thread1 t1 = new Thread1();
        t1.start();
    }

}

第二種執行緒建立的例項

建立的執行緒類:

package com.Thread;

public class Thread2 implements Runnable{

    @Override
    public void run(){
        for(int i = 0; i < 10;i ++){
            System.out.println(i);
        }
    }

}       

呼叫執行緒的類:

package com.Thread;

public class TestThread {

    public static void main(String[] args){
        Thread2 t2 = new Thread2();
        Thread thread = new Thread(t2);
        thread.start();
    }

}

相關問題

注意:使用執行緒時,儘量不產生死鎖。死鎖發生在兩個執行緒之間,簡而言之就是互相佔用對方的資源,但是又想獲取物件的資源,最終導致了阻塞,也就是死鎖。如何解決死鎖,可以檢視死鎖的介紹和解決方法。以下便是死鎖的例子:

執行緒A:

package com.Thread;

public class A extends Thread{

    @Override
    public void run(){
        synchronized(A.class){
            for(int i = 0;i < 15;i ++){
                System.out.println(i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName());
            synchronized(B.class){
                System.out.println(Thread.currentThread().getName());
            }
        }
    }

}

執行緒B:

package com.Thread;

public class B extends Thread{

    @Override
    public void run(){
        synchronized(B.class){
            for(int i = 0;i < 15;i ++){
                System.out.println(i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName());
            synchronized(A.class){
                System.out.println(Thread.currentThread().getName());
            }
        }
    }

}