1.進(jìn)程和線程
?1.1.進(jìn)程和線程
??1.操作系統(tǒng)中運(yùn)行多個(gè)軟件
??2.一個(gè)運(yùn)行中的軟件可能包含多個(gè)進(jìn)程
??3.一個(gè)運(yùn)行中的進(jìn)程可能包含多個(gè)線程
?1.2.CPU線程和操作系統(tǒng)線程
??1.2.1.CPU線程
????1.多核CPU的每個(gè)核各自對(duì)立運(yùn)行灸姊,因此每個(gè)核一個(gè)線程
????2.「四核?線程」:CPU硬件方在硬件級(jí)別對(duì)CPU進(jìn)行了一核多線程的支持(本質(zhì)上依然是每個(gè)核一個(gè)線程)
??1.2.2.操作系統(tǒng)線程
????1.操作系統(tǒng)利用時(shí)間分片的方式,把CPU的運(yùn)行拆分給多條運(yùn)行邏輯迅办,即為操作系統(tǒng)的線程肴裙。
2.線程使用
?2.1.Thread和Runnable
//Thread
Thread thread = new Thread(){
@Override
public void run() {
Log.e("TAG","Thrad started------Thread");
}
};
thread.start();
//Runnable
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.e("TAG","Thrad started------Runnable");
}
};
Thread thread1 = new Thread(runnable);
thread1.start();
?2.2.Executor 和線程池
??常用:newCachedThreadPool()
//Executor
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.e("TAG","runnable----------------------");
}
};
Executor executor = Executors.newCachedThreadPool();
executor.execute(runnable);
executor.execute(runnable);
executor.execute(runnable);
3.線程同步與線程安全
?3.1.synchronized方法
private synchronized void count(int newValue) {
x = newValue;
y = newValue;
if (x != y) {
System.out.println("x: " + x + ", y:" + y);
}
}
問題:
??當(dāng)我們兩個(gè)線程同時(shí)調(diào)用count方法趾唱,如果不添加synchronized關(guān)鍵字,會(huì)出現(xiàn)x蜻懦!=y的情況甜癞。
因?yàn)楫?dāng)線程1執(zhí)行到count方法的x=newValue,突然切換時(shí)間片切換到線程2執(zhí)行到y(tǒng) = newValue,此時(shí)x就會(huì)不等于y宛乃,此時(shí)就會(huì)出現(xiàn)數(shù)據(jù)問題悠咱,數(shù)據(jù)不同步問題。
解決:
??添加synchronized關(guān)鍵字后征炼,會(huì)把count方法作為一個(gè)整體析既,當(dāng)線程1的count方法未執(zhí)行行完成,此時(shí)其他線程執(zhí)行count方法谆奥,此時(shí)線程1還持有鎖眼坏,線程2只能等待線程1執(zhí)行完成后才能執(zhí)行count方法。保證數(shù)據(jù)同步問題酸些。
?3.2.synchronized代碼塊
private void count(int newValue) {
synchronized(this){
x = newValue;
y = newValue;
if (x != y) {
System.out.println("x: " + x + ", y:" + y);
}
}
}
synchronized關(guān)鍵字的本質(zhì):
??1.保證方法內(nèi)部或代碼塊內(nèi)部資源(數(shù)據(jù))的互斥訪問宰译,即同一時(shí)間,由同一個(gè)Monitor(可認(rèn)為是synchronized關(guān)鍵字)監(jiān)視的代碼魄懂,最多只能有一個(gè)線程在訪問沿侈。
??2.保證線程之間對(duì)監(jiān)視資源的數(shù)據(jù)同步,即市栗,任何線程在獲取到Monitor后的第一時(shí)間缀拭,會(huì)先將共享內(nèi)存中的數(shù)據(jù)復(fù)制到自己的緩存中,任何線程在釋放Monitor的第一時(shí)間會(huì)先將緩存中的數(shù)據(jù)復(fù)制到共享內(nèi)存中填帽。
volatile關(guān)鍵字
??1.保證加了volatile關(guān)鍵字的字段的操作具有原子性和同步性蛛淋,其中原子性相當(dāng)于實(shí)現(xiàn)了針對(duì)單一字段的線程間互斥訪問,因此volatile可以看做是簡(jiǎn)化版的synchronized
??2.volatile關(guān)鍵字只對(duì)基本類型(byte盲赊,short,int敷扫,long哀蘑,char诚卸,float,double绘迁,boolean)的賦值操作和對(duì)象的引用賦值操作有效合溺。
4.總結(jié)
?4.1.線程安全問題的本質(zhì):
??在多個(gè)線程訪問共同的資源時(shí),在某一個(gè)線程對(duì)資源進(jìn)行寫操作的中途(寫入已經(jīng)開始缀台,但還沒結(jié)束)棠赛,其他線程對(duì)這個(gè)寫了一半的資源進(jìn)行了讀操作,或者基于這個(gè)寫了一半的資源進(jìn)行了寫操作膛腐,導(dǎo)致數(shù)據(jù)出現(xiàn)錯(cuò)誤睛约。
?4.2.鎖機(jī)制的本質(zhì):
??1.通過對(duì)共享資源進(jìn)行訪問限制,讓同一時(shí)間只有一個(gè)線程可以訪問資源哲身,保證了數(shù)據(jù)的準(zhǔn)確性辩涝。
??2.不論是線程安全問題,還是針對(duì)線程安全問題所衍生出的鎖機(jī)制勘天,他們的核心都是在共享的資源怔揩,而不是在某個(gè)方法或者某幾行代碼。