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鎖的方法 }
打印繼續向下看
結論:同一個類的不同鎖,多線程在執行鎖住的代碼時,多線程不互聯影響。