溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

多線程同步基礎

發(fā)布時間:2020-07-03 17:29:16 來源:網絡 閱讀:438 作者:jethai 欄目:開發(fā)技術


主線程執(zhí)行完要等待其他線程執(zhí)行完,才退出虛擬機



主線程執(zhí)行完需要讓其他線程也結束,可設置為守護線程,守護線程必須在線程啟動前開啟



實現方式和繼承方式的區(qū)別:

實現方式好處避免了但繼承的局限性(不能繼承其他類,只能繼承Thread類)

定義線程時,建議使用實現方式。

兩種方式區(qū)別:

繼承Thread:線程代碼存放Thread子類的run方法中

實現Runnable:線程代碼存放接口子類的run方法中


同步的前提:
1,必須要有兩個或者兩個以上的線程。
2,必須是多個線程使用同一個鎖(同一個對象)。

必須保證同步中只能有一個線程在運行。


如何判斷程序是否有安全問題:
1,明確哪些代碼是多線程運行代碼。
2,明確共享數據。
3,明確多線程運行代碼中哪些語句是操作共享數據的。


同步的兩種表現形式:同步代碼塊和同步函數

同步代碼塊


Object obj = new Object();

synchronized(obj)
            {
               //todo
            }


同步函數(使用的鎖是this)

同步函數被靜態(tài)修飾后使用的鎖不再是this,因為靜態(tài)方法中不可以有this,

靜態(tài)的同步方法使用的鎖是該方法所在類的字節(jié)碼文件對象。 類名.class

public synchronized void add(int n)
    {
       
       
    }



    public static synchronized void show()
    {
        
    }

同步代碼塊和同步函數要使用同一把鎖需要讓同步代碼塊的鎖設為this或者類名.class


多線程單例最好寫成餓漢式(函數里面只有一句話)

class Single
{
    private static final Single s = new Single();
    private Single(){}
    public static Single getInstance()
    {
        return s;
    }
}


懶漢式的延時加載多線程訪問時會出現安全問題,同步鎖是該類的字節(jié)碼對象

class Single
{
    private static Single s = null;
    private Single(){}


    public static  Single getInstance()
    {
        if(s==null)
        {
            synchronized(Single.class)
            {
                if(s==null)
                    //--->A;
                    s = new Single();
            }
        }
        return s;
    }
}





同步弊端死鎖-同步嵌套,鎖不一樣

/*
死鎖。
同步中嵌套同步。

*/

class Ticket implements Runnable
{
    private  int tick = 1000;
    Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(obj)
                {
                    show();
                }
            }
        }
        else
            while(true)
                show();
    }
    public synchronized void show()//this
    {
        synchronized(obj)
        {
            if(tick>0)
            {
                try{Thread.sleep(10);}catch(Exception e){}
                System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
            }
        }
    }
}


class  DeadLockDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        try{Thread.sleep(10);}catch(Exception e){}
        t.flag = false;
        t2.start();


    }
}


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

    public void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(MyLock.locka)
                {
                    System.out.println(Thread.currentThread().getName()+"...if locka ");
                    synchronized(MyLock.lockb)
                    {
                        System.out.println(Thread.currentThread().getName()+"..if lockb");                    
                    }
                }
            }
        }
        else
        {
            while(true)
            {
                synchronized(MyLock.lockb)
                {
                    System.out.println(Thread.currentThread().getName()+"..else lockb");
                    synchronized(MyLock.locka)
                    {
                        System.out.println(Thread.currentThread().getName()+".....else locka");
                    }
                }
            }
        }
    }
}


class MyLock
{
    static Object locka = new Object();
    static Object lockb = new Object();
}

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





向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI