国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

以銀行取錢為例模擬Java多線程同步問題完整代碼

2024-07-13 10:14:56
字體:
來源:轉載
供稿:網友

簡單了解下在操作系統中進程和線程的區別:

  進程:每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷,一個進程包含1--n個線程。(進程是資源分配的最小單位)

  線程:同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。(線程是cpu調度的最小單位)

  線程和進程一樣分為五個階段:創建、就緒、運行、阻塞、終止。

  多進程是指操作系統能同時運行多個任務(程序)。

  多線程是指在同一程序中有多個順序流在執行。首先存錢取錢的這個操作,應該是線程操作的,可以有很多的顧客,這意思就是得有多個線程,多個線程之間共同操作一個銀行,銀行的金額就需要同步。才能保證線程安全。

所以,下面就把這個代碼的實例放這,有不對的地方,還請指出來哈。因為有個老鐵問這個多線程的代碼。

首先是銀行,這個對象model的創建。

java;">package com.lxk.threadTest.bank;/**  * 銀行model,一個總金額屬性。  * <p>  *  * @author lxk on 2017/6/26  */public class Bank {	/**    * 給銀行個啟動資金,不然怎么干生意呢。    */	private int sum = 200;	//這個從來不這么用,但也算是正確的一種加鎖的機制:同步代碼塊。 	//Object obj = new Object(); 	/**    * 存錢    * 要是不加[synchronized--同步函數],則會出現多線程安全問題。    */	public synchronized void add(int n) {		//synchronized (obj) { 		sum = sum + n;		try {			Thread.sleep(10);		}		catch (Exception ignore) {		}		//當存錢次數變多的時候,就可以發現,存錢的線程確實是2個在交替執行存錢這個動作的。 		System.out.println(Thread.currentThread().getName() + "...sum=" + sum);		//}	}	/**    * 取錢    * 要是不加[synchronized--同步函數],則會出現多線程安全問題。    */	public synchronized void reduce(int n) {		if (sum - n >= 0) {			sum = sum - n;		} else {			System.out.println("bank's money is not enough !");		}		try {			Thread.sleep(30);		}		catch (Exception ignore) {		}		//當存錢次數變多的時候,就可以發現,存錢的線程確實是2個在交替執行存錢這個動作的。 		System.out.println(Thread.currentThread().getName() + "...sum=" + sum);	}}

在代碼里面有存和取2個方法,這2個方法,以及一個總金額,里面有部分被注釋掉的代碼,那個是簡單易懂好理解的,多線程加鎖互斥,保證線程間同步的方法。

但是這個是不常用的方法,常用的就是使用synchronized這個關鍵字來修飾同步方法。

客戶對象的model

package com.lxk.threadTest.bank;/**  * 顧客,實現runnable()接口,多個人可以一起存錢  *  * @author lxk on 2017/6/26  */public class Customer implements Runnable {	/**    * 存錢類型    */	static final String TYPE_ADD = "add";	/**    * 取錢類型    */	static final String TYPE_REDUCE = "reduce";	/**    * 銀行    */	private Bank bank;	/**    * 對錢的操作類型,存錢or取錢    */	private String type;	/**    * 操作的次數,理論上是個正數    */	private int time;	/**    * 要存或者取多少錢    */	private int money;	public Customer() {	}	public Customer(Bank bank, String type, int time, int money) {		this.bank = bank;		this.type = type;		this.time = time;		this.money = money;	}	@Override 	  public void run() {		for (int x = 0; x < time; x++) {			if (TYPE_ADD.equals(type)) {				bank.add(money);			} else if (TYPE_REDUCE.equals(type)) {				bank.reduce(money);			}		}	}}

客戶對象,因為可以很多個客戶同時訪問一個銀行,所以,這個存錢取錢的操作就用線程來實現。

屬性就構造方法傳值了。

main方法

package com.lxk.threadTest.bank;/**  * 銀行存錢的多線程實例  * <p>  * 【需求:】  * 銀行有一個金庫。  * 有兩個儲戶分別存或者取n * 100。  * 目的:該程序是否有安全問題,如果有,如何解決?  * <p>  * 【如何找問題:】  * 1,明確哪些代碼是多線程運行代碼。  * 2,明確共享數據。  * 3,明確多線程運行代碼中哪些語句是操作共享數據的。  *  * @author lxk on 2017/6/26  */public class Main {	public static void main(String[] args) {		//一個銀行and多個客戶 		Bank bank = new Bank();		int time = 10000;		int money = 100;		//這個客戶存錢 		Customer c1 = new Customer(bank, Customer.TYPE_ADD, time, money);		//這個客戶取錢 		Customer c2 = new Customer(bank, Customer.TYPE_REDUCE, time, money);		Thread t1 = new Thread(c1);		Thread t2 = new Thread(c2);		t1.start();		t2.start();	}}

上述代碼實際運行效果如下圖。

java,多線程同步,實例,多線程同步例子,java多線程實例,java多線程開發實例,java多線程例子

這個存取錢的次數要是小了,就可能會看到2個線程有先后順序,所以,這個次數咱整多點,然后,就看到如圖所示的情況,線程1是取錢的,線程0時存錢的,可以看到2個線程是互相交錯執行的,有存有取,沒有規律可言。

這個就保證了數據的同步了。

至于如何才能不同步,也就是異常的現象,

你可以把add方法的這個synchronized關鍵字去掉之后,把次數調小一點改成3次,sum的初始值給設置成0.你再試試代碼,

就會發現所謂的不同步現象。

java,多線程同步,實例,多線程同步例子,java多線程實例,java多線程開發實例,java多線程例子

上圖的右邊就是不同步的結果,2個人每次存100,存三次,總數是不是得,100,200,300,400,500,600.得長。

但是,運行結果卻不是的,

這個時候,你再把synchronized給add方法加上去,就會出現左邊的圖的結果,這個就是正確的結果。

我是為了,有存有取,所以,就又加了個方法。代碼就變成上面的樣子啦。

差不多都是線程間同步的例子啦。

我就簡單記錄下代碼。用的時候,可以分分鐘就拿出來。

總結

以上就是本文關于以銀行取錢為例模擬Java多線程同步問題完整代碼的全部內容,希望對大家有所幫助。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乳山市| 溧水县| 金乡县| 临夏市| 雅安市| 南漳县| 辉县市| 乌兰浩特市| 宁阳县| 武城县| 武安市| 佳木斯市| 富阳市| 公安县| 周口市| 文化| 洪雅县| 铜山县| 南康市| 二连浩特市| 鄂尔多斯市| 衡阳县| 车致| 九江市| 荃湾区| 灵台县| 玉溪市| 休宁县| 都昌县| 章丘市| 三台县| 和林格尔县| 莒南县| 安岳县| 甘肃省| 集安市| 内乡县| 望城县| 桓台县| 晋城| 禹州市|