天天看點

Java-多線程基本

Java-多線程基本

一 相關的概念

程序:是一個正在執行中的程式

每個程序都有一個執行的順序,該順序是一個執行路徑,或者叫一個控制單元

線程:就是程序中的一個獨立的控制單元,線程在控制着程序的執行

注意 :

一個程序至少有一個線程

Java VM啟動的時候會有一個程序java.exe

該程序中至少一個線程負責java程式的執行,并且這個線程執行的代碼在main方法中

該線程稱為主線程

JVM啟動不止一個線程,還有負責垃圾回收機制的線程

二 自己定義建立線程

須要用到Thread類

建立方法一:

1.定義類繼承自Thread

2.複寫Thread中的run方法

3.調用線程的start方法,該方法有兩個作用:啟動線程。調用run方法

建立方法二:

1.定義類實作Runnable接口

2.覆寫Runnable接口中的run方法

3.通過Thread類建立線程對象

4.将Runnable接口的子類對象作為實際參數傳遞給Thread類的構造函數:

原因是自己定義的run方法所屬的對象是Runnable接口的子類對象

是以要讓線程去指定對象的run方法。就必須明白run方法的所屬對象

5.調用Thread類的start方法開啟線程并調用Runnable接口子類的run方法

兩種方式的差别:

方法二實作方式的優點:避免了單繼承的局限性,建議使用實作的方式

多線程的特性:随機性。因為cpu的分時排程規則(在某一個時刻,cpu隻執行一個程式,cpu在執行過程中做着高速的切換),至于執行的時間,cpu說的算

對象調用run和start的差别:

start:開啟線程并執行該線程的run方法

run:不過對象調用方法,并且線程建立了,并沒有執行

多線程的執行狀态:

建立,執行,消亡,堵塞。當機

例如以下圖:

Java-多線程基本

多線程經常使用的方法:

static Thread currentThread()擷取目前線程對象

getName()擷取線程名稱。線程名稱預設格式為Thread-0(1,2,3…..)

setName或者構造函數能夠設定線程名稱

三 多線程的安全問題:

解決線程操作資料時的時間差問題須要用到

1。同步代碼塊

synchronized(對象鎖)
{

    須要同步的代碼。
}
      

2,同步函數

就是将synchronized關鍵字加到函數上

public synchronized void Test()
{

}
      

怎樣找出線程的安全隐患:

1.明白哪些代碼是多線程執行代碼

2.明白共享的資料

3.明白多線程執行代碼中哪些語句是操作共享資料的

三 鎖

鎖:

鎖就是一個對象

同步函數的鎖死this,

靜态同步函數的鎖是該方法所在類的位元組碼檔案對象。類名.class對象:靜态方法中不能夠定義this,靜态方法進入記憶體,記憶體中還沒有本類的對象

可是一定有該類相應的位元組碼檔案對象,類名.class。該對象的類型是class

死鎖:兩個線程互相争奪鎖的情況

以下是一個面試題:寫一個死鎖的Demo

class Test implements Runnable
{
    private boolean flag;
    Test(boolean p_flag)
    {
        this.flag = p_flag;
    }

    public void run()
    {
        if (flag)
        {
            while (true)
            {
                synchronized(MyLock.locka)
                {
                    System.out.println("if locka");
                    synchronized(MyLock.lockb)
                    {
                        System.out.println("if lockb");

                    }
                }
            }
        }
        else
        {
            while (true)
            {
                    synchronized(MyLock.lockb)
                {
                     System.out.println("if lockb");
                                     synchronized(MyLock.locka)
                         {
                        System.out.println("if locka");

                     }
                     }
            }

        }

    }

}
//鎖對象
class MyLock
{
    static Object locka = new Object();
    static Object lockb = new Object();

}


class TestDemo
{
    public static void main(String[] args)
    {
        Thread t1 = new Thread(new Test(true));
        Thread t2 = new Thread(new Test(false));
        t1.start();
        t2.start();


    }
}
      

四 多線程與單例設計模式:

class Singel 
{
    private static Singel s = null;
    private Singel();

    public static Singel getInstance()
    {
            //雙重推斷能夠解決效率低的問題
        if (null == s)
        {
            //synchronized關鍵字比起在函數上同步更加高效
            synchronized(Singel.class)//使用的本類檔案的鎖
            {
                if (null == s)
                {
                    s = new Singel();
                }
            }
            return s;
        }

    }
}