java并发访问_Java并发访问
1 線程安全
線程安全就是多線程訪問時,采用了加鎖機制,當一個線程訪問該類的某個數據時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程才可使用。不會出現數據不一致或者數據污染。 線程不安全就是不提供數據訪問保護,有可能出現多個線程先后更改數據造成所得到的數據是臟數據
2 局部變量并不會數據共享
局部變量,不同線程的并不共享,所以并不會發生覆蓋
PrivateNum p=new PrivateNum();
MyThread threadA=new MyThread('A',p);
MyThread threadB=new MyThread('B',p);
threadA.start();
threadB.start();
public void test( char i) {
try {
int num=0;
- - - - - - -
}
catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}}
3 實例成員變量數據共享
PrivateNum p=new PrivateNum();
MyThread threadA=new MyThread('A',p);
MyThread threadB=new MyThread('B',p);
threadA.start();
threadB.start();
public void test( char i) {
int num=0;
try {
- - - - - - -
}
catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}}
線程AB訪問的是同一個變量(指向同一個地址),所以這個時候會發生覆蓋,同時這里出現了線程安全問題
4 synchronized關鍵字可以避免線程安全問題
如果多個線程訪問的是同一個對象方法中的局部變量,那么這個變量并不共享,線程AB對此變量的操作將互不影響
如果多個線程訪問的是同一個對象方法中的成員變量,那么這個變量共享,如果不處理好線程問題,可能會出現線程安全問題
通過synchronized關鍵字可以使方法同步
5 多個線程訪問的是兩個不同實例的同一個同步方法
public static void main(String[] args) {
PrivateNum p1=new PrivateNum();
PrivateNum p2=new PrivateNum();
MyThread threadA=new MyThread('A',p1);
MyThread threadB=new MyThread('B',p2);
threadA.start();
threadB.start();
}}
這是因為這里是兩個鎖,創建了p1和p2對象,創建的是兩個鎖,鎖對象不同不造成互斥作用
6 多線程調用同一個實例的兩個不同(一個同步,一個非同步)方法
MyThread threadA=new MyThread('A',p1);
MyThread2 threadB=new MyThread2('B',p1);
threadA.start();
threadB.start();
線程B可以異步調用非同步的方法
7 死鎖
線程AB開始執行時,因為鎖不同,所以不互斥,A當執行到另一個同步代碼塊(鎖2)的時候,由于這個時候鎖給線程B占有了,所以只能等待,同樣B線程也是如此,AB互相搶對方的鎖,但是所以造成了死鎖
8 總結
多個線程調用的不同實例的同步方法,線程不互斥。
如果兩個線程的鎖對象一樣(都是p1),兩個線程分別調用同步方法和非同步方法,線程不會同步執行。
但是如果調用兩個不同的同步方法,因為鎖對象一致,兩個線程同步執行。
設想一個情況,有一個實例有兩個方法,一個修改值(synchronized),一個讀值(非synchronized),此時兩個線程一個修改值,一個讀取值,這個時候因為這兩個線程并不會掙搶鎖,兩個線程互不影響,那么此時可能就會出現一種情況,線程A還沒修改完,線程B就讀取到沒有修改的值。這就是所謂的臟讀。
重入鎖,一個獲得的鎖的線程沒執行完可以繼續獲得鎖。
線程占用鎖的時候,如果執行的同步出現異常,會將鎖讓出。
父類方法同步,子類重寫該方法(沒有synchronized關鍵字修飾),是沒有同步作用的。
同步代碼塊的鎖對象可以是本對象,也可以是其他對象。同一個鎖對象可以產生互斥作用,不同鎖對象不能產生互斥作用
一個方法中有同步代碼塊和非同步代碼塊,同步代碼塊的代碼是同步執行的(塊里的代碼一次執行完),而非同步代碼塊的代碼可以異步執行
一個對象中的不同同步代碼塊是互斥的,執行完一個代碼塊再執行另一個代碼塊
同步代碼塊(this)和synchronized方法的鎖定的都是當前對象 this
Class類也可以是鎖,Class鎖的實現可以通過靜態的synchronizd方法,也可以通過靜態方法里面的同步代碼塊(鎖對象為Class)
靜態類的同步方法鎖對象還是該類的一個實例
volitate增加了實例變量在對個線程之間的可見性,保證我們獲得的是變量的最新值。
volatile在讀上面保持了同步作用,但是在寫上面不保持同步
synchronized的同步作用不僅保證了對同一個鎖線程的互斥,還保證了數據的同步
volatile對比synchronized
兩者修飾的不同,volatile修飾的是變量,synchronized修飾的是方法和代碼塊
兩者的功能不同。volatile保證數據的可見性,synchronized是線程同步執行(間接保證數據可見性,讓線程工作內存的變量和公共內存的同步)
volatile性能比synchronized性能高
總結
以上是生活随笔為你收集整理的java并发访问_Java并发访问的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: deebot扫地机器人怎么清洁_扫地机器
- 下一篇: flexcell控件 许可证信息没有找到