非線程安全
其實(shí)會(huì)在多個(gè)線程對(duì)同一個(gè)對(duì)象中的實(shí)例變量進(jìn)行并發(fā)訪問(wèn)時(shí)產(chǎn)生。產(chǎn)生的后果就臟讀
,也就是得到的數(shù)據(jù)是被修改過(guò)的。而線程安全
就是以獲得的實(shí)例變量的值是經(jīng)過(guò)同步處理過(guò)的,不會(huì)出現(xiàn)臟讀的現(xiàn)象。
非線程安全
問(wèn)題存在于實(shí)例變量
中,如果是方法內(nèi)部的私有變量,則不存在非線程安全
問(wèn)題,這是方法內(nèi)部的變量是私有的特性造成的。
【注意】:關(guān)鍵字
synchronized
取得的鎖都是對(duì)象鎖,而不是把一段代碼或方法當(dāng)作鎖。哪個(gè)線程先執(zhí)行帶synchronized
關(guān)鍵字的方法,哪個(gè)線程就持有該方法所屬對(duì)象的鎖Lock,那么其他線程只能呈等待狀態(tài) 【前提是多個(gè)線程訪問(wèn)的事同一個(gè)對(duì)象!!!】
synchronized
方法與鎖對(duì)象:
public class ThreadA extends Thread {
private MyObject object;
public ThreadA(MyObject object){
super();
this.object = object;
}
@Override
public void run() {
super.run();
object.methodA();
}
}
public class ThreadB extends Thread{
private MyObject object;
public ThreadB(MyObject object){
super();
this.object = object;
}
@Override
public void run() {
super.run();
object.methodA();
}
}
public class Run {
public static void main(String[] args) {
MyObject object = new MyObject();
ThreadA a = new ThreadA(object);
a.setName("A");
ThreadB b = new ThreadB(object);
b.setName("B");
a.start();
b.start();
}
}
public class MyObject {
public void methodA(){
try {
System.out.println("begin methodA threadName="+Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
}
運(yùn)行結(jié)果1:
運(yùn)行結(jié)果1
在methodA方法前加上synchronized可得到運(yùn)行結(jié)果2
synchronized public void methodA()
運(yùn)行結(jié)果2
鎖重入:
在使用sychronized關(guān)鍵字時(shí),當(dāng)一個(gè)線程得到一個(gè)對(duì)象鎖后,再次請(qǐng)求此對(duì)象鎖時(shí)是可以再次得到該對(duì)象的鎖。
可重入鎖的概念是:自己可以再次獲取自己的內(nèi)部鎖
當(dāng)存在父子類繼承關(guān)系時(shí),子類完全可以通過(guò)“可重入鎖”調(diào)用父類的同步方法。