今天學習了的主要內容:
1.多執行緒存取同一個共用的資料情況解析
2.java記憶體模型JMM
3.建立多執行緒呼叫一個變數的情況
多執行緒存取同一個共用的資料情況解析:
靜態域、陣列還有範例都在堆中被建立,都能夠被任何執行緒存取。
可能會被多個執行緒並行存取然後被修改,這種情況沒有任何警告。
java記憶體模型JMM:
它主要描述了程式中的變數在啥時候以啥方式和順序以及怎麼儲存
到主記憶體中,以及以什麼樣的方式從主記憶體中讀取出來。
java程式當中執行緒總共有兩種記憶體使用型別:
工作記憶體(working memory)和主記憶體(main memory)。
主記憶體就是所有執行緒共用的記憶體區域,可以用於執行緒之間互相通訊。
每個執行緒都有屬於自己的用於儲存使用的區域性變數的棧,都有自己的工作記憶體。
原子性(atomicity):除了long和double外,物件屬性的讀寫是原子的。
可見性(visibility):一個執行緒怎樣讀取另一個執行緒工作空間修改過的值
當某個執行緒首次讀取主空間變數的值時,它有可能是初始值也可能是其他執行緒寫入後 的值。
volatile(不穩定的)變數總是寫入主記憶體中,也總是從主記憶體中讀取變數的值。
當執行緒終止時該執行緒從主空間得到的在工作空間操作的值將被寫入主記憶體。
執行緒進入同步塊時工作空間中的值將被讀取。
有序性(ordering):執行緒中執行的操作都是有序的。
建立多執行緒呼叫一個變數的情況
程式碼:
Bank類(模擬銀行的賬戶提供提款功能):
package LessonForThread05;
public class Bank
{
protected int money = 1000;
public int getMoney()
{
return money;
}
public void setMoney(int money)
{
this.money = money;
}
public void drawMoney(int sum)
{
if (sum <= 0)
{
System.out.println("您輸入的數值不正確!");
return;
}else if (sum > this.getMoney())
{
System.out.println("您輸入的金額超出自身賬戶餘額了!");
return;
}else
{
try
{
Thread.sleep(2000);//在執行取款前,先讓他休息一秒,使執行緒交叉取款
} catch (InterruptedException e)
{
e.printStackTrace();
}
this.setMoney((this.getMoney() - sum));
System.out.println("本次取款:"+sum+"元,賬戶餘額為:"+this.getMoney());
}
}
}
Person類(個人提款動作執行緒實現體):
package LessonForThread05;
public class Person implements Runnable
{
protected Bank account;
public Person(Bank account)
{
this.account = account;
}
@Override
public void run()
{
this.account.drawMoney(300);
}
}
Test類(實現多執行緒呼叫同一個屬性):
package LessonForThread05;
public class Test
{
public static void main(String[] args)
{
Bank b1 = new Bank();
for (int i=0; i<10; i++)//反覆建立十個不同的執行緒來呼叫取錢方法。
{
Thread t = new Thread(new Person(b1));
t.start();
}
try //主執行緒讓出時間來給子執行緒取錢
{
Thread.sleep(10000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("完畢!目前餘額:"+b1.getMoney());
}
}
本篇部分文字來源於:
咕嘟咖啡楊海濱老師 — 《java程式語言高階特性》
在這裡十分感謝老師能夠給我帶來學習的激情。
2020.10.23
可以轉載我的學習日記但請註明出處,謝謝。
本文章是本人學習筆記,不進行任何商用!也請別拿去商用!只為記錄本人學習歷程。
畢