java多線程知識匯總(三)如何選擇鎖?如何加鎖


1.鎖,保證的是被鎖的代碼,一次執行完畢才能被其他線程執行,鎖保證了一個線程執行過程中不被其他線程打斷。以保證數據的准確性。

2。數據的讀寫過程,是有沖突的,當一個線程正在讀數據,另一個線程正在寫同一個數據,就有可能導致數據不准確,造成臟數據。就要保證讀寫分開時間段。即加鎖。

3.如果想要保證共享對象的一個方法按序執行,則在這個方法上加鎖。

4.多個方法加同一個鎖:在多個方法上加同一個鎖。如果想保證讀寫能讀取到准確數據,則在同一成員變量的對應讀寫方法上加同一個鎖,同一個鎖。保證讀寫正常。

5.同一個類中加不同的鎖,比如一個加的this鎖,一個加的object的鎖,則此兩個方法不受任何影響,多線程可以分別同時運行這兩種各方法。

但是如果一個類的躲個方法加同一個鎖,則只能按序訪問。

下面舉例說明,同一個類加不同的鎖,一個this鎖,一個同步代碼塊的object的鎖。

單例對象包括不同的鎖:

public class Student {
    private String age = "12";
    private String name = "Tome";    
    private static Student student = new Student();
    private Object object = new Object();
    
    public void setName(String string) {
        synchronized (object) {
            System.out.println("i am running");
        }    
    }
    synchronized public String getNameAndAge() {
        return name+":"+age;
    }
    synchronized public void setNameAndAge(String name,String age) {
        this.name = name;
        this.age = age;
    }

    private Student()
    {        
    }
    public static Student GetInstace() {
            return student;
    }
}

線程1負責占用單例對象的this鎖,且sleep讓它一直占用

public class MyThread extends Thread {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        Student.GetInstace().setNameAndAge("111", "111");//占用this鎖的方法
        try {
            System.out.println("i am sleeping");//打印輸出我在休眠,一直占用this鎖
            Thread.currentThread().sleep(500);//睡眠,一直占用this鎖,因為調用的是this鎖的方法
            System.out.println("i wake up");//打印輸出我占用完畢
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

線程2負責執行object同步塊代碼,同步塊調用的是另一個鎖,即object鎖。

public class AppMain implements Runnable{

    public static void main(String[] args) {
        AppMain appMain = new AppMain();
        MyThread thread2 = new MyThread();
        thread2.start();
        for(int i =0;i<200;i++)
        {
        Thread thread1 = new Thread(appMain);
        thread1.start();    
        }
    }    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        Student.GetInstace().setName("3333");//調用的是object鎖的方法
    }

 

 

打印繼續向下看

 

結論:同一個類的不同鎖,多線程在執行鎖住的代碼時,多線程不互聯影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM