欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

以銀行取錢(qián)為例模擬Java多線程同步問(wèn)題完整代碼

 更新時(shí)間:2017年12月19日 10:36:22   作者:李學(xué)凱  
這篇文章主要介紹了以銀行取錢(qián)為例模擬Java多線程同步問(wèn)題完整代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下。

簡(jiǎn)單了解下在操作系統(tǒng)中進(jìn)程和線程的區(qū)別:

  進(jìn)程:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文),進(jìn)程間的切換會(huì)有較大的開(kāi)銷,一個(gè)進(jìn)程包含1--n個(gè)線程。(進(jìn)程是資源分配的最小單位)

  線程:同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線程切換開(kāi)銷小。(線程是cpu調(diào)度的最小單位)

  線程和進(jìn)程一樣分為五個(gè)階段:創(chuàng)建、就緒、運(yùn)行、阻塞、終止。

  多進(jìn)程是指操作系統(tǒng)能同時(shí)運(yùn)行多個(gè)任務(wù)(程序)。

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

所以,下面就把這個(gè)代碼的實(shí)例放這,有不對(duì)的地方,還請(qǐng)指出來(lái)哈。因?yàn)橛袀€(gè)老鐵問(wèn)這個(gè)多線程的代碼。

首先是銀行,這個(gè)對(duì)象model的創(chuàng)建。

package com.lxk.threadTest.bank;
/** 
 * 銀行model,一個(gè)總金額屬性。 
 * <p> 
 * 
 * @author lxk on 2017/6/26 
 */
public class Bank {
	/** 
   * 給銀行個(gè)啟動(dòng)資金,不然怎么干生意呢。 
   */
	private int sum = 200;
	//這個(gè)從來(lái)不這么用,但也算是正確的一種加鎖的機(jī)制:同步代碼塊。 
	//Object obj = new Object(); 
	/** 
   * 存錢(qián) 
   * 要是不加[synchronized--同步函數(shù)],則會(huì)出現(xiàn)多線程安全問(wèn)題。 
   */
	public synchronized void add(int n) {
		//synchronized (obj) { 
		sum = sum + n;
		try {
			Thread.sleep(10);
		}
		catch (Exception ignore) {
		}
		//當(dāng)存錢(qián)次數(shù)變多的時(shí)候,就可以發(fā)現(xiàn),存錢(qián)的線程確實(shí)是2個(gè)在交替執(zhí)行存錢(qián)這個(gè)動(dòng)作的。 
		System.out.println(Thread.currentThread().getName() + "...sum=" + sum);
		//}
	}
	/** 
   * 取錢(qián) 
   * 要是不加[synchronized--同步函數(shù)],則會(huì)出現(xiàn)多線程安全問(wèn)題。 
   */
	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) {
		}
		//當(dāng)存錢(qián)次數(shù)變多的時(shí)候,就可以發(fā)現(xiàn),存錢(qián)的線程確實(shí)是2個(gè)在交替執(zhí)行存錢(qián)這個(gè)動(dòng)作的。 
		System.out.println(Thread.currentThread().getName() + "...sum=" + sum);
	}
}

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

但是這個(gè)是不常用的方法,常用的就是使用synchronized這個(gè)關(guān)鍵字來(lái)修飾同步方法。

客戶對(duì)象的model

package com.lxk.threadTest.bank;
/** 
 * 顧客,實(shí)現(xiàn)runnable()接口,多個(gè)人可以一起存錢(qián) 
 * 
 * @author lxk on 2017/6/26 
 */
public class Customer implements Runnable {
	/** 
   * 存錢(qián)類型 
   */
	static final String TYPE_ADD = "add";
	/** 
   * 取錢(qián)類型 
   */
	static final String TYPE_REDUCE = "reduce";
	/** 
   * 銀行 
   */
	private Bank bank;
	/** 
   * 對(duì)錢(qián)的操作類型,存錢(qián)or取錢(qián) 
   */
	private String type;
	/** 
   * 操作的次數(shù),理論上是個(gè)正數(shù) 
   */
	private int time;
	/** 
   * 要存或者取多少錢(qián) 
   */
	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);
			}
		}
	}
}

客戶對(duì)象,因?yàn)榭梢院芏鄠€(gè)客戶同時(shí)訪問(wèn)一個(gè)銀行,所以,這個(gè)存錢(qián)取錢(qián)的操作就用線程來(lái)實(shí)現(xiàn)。

屬性就構(gòu)造方法傳值了。

main方法

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

上述代碼實(shí)際運(yùn)行效果如下圖。

這個(gè)存取錢(qián)的次數(shù)要是小了,就可能會(huì)看到2個(gè)線程有先后順序,所以,這個(gè)次數(shù)咱整多點(diǎn),然后,就看到如圖所示的情況,線程1是取錢(qián)的,線程0時(shí)存錢(qián)的,可以看到2個(gè)線程是互相交錯(cuò)執(zhí)行的,有存有取,沒(méi)有規(guī)律可言。

這個(gè)就保證了數(shù)據(jù)的同步了。

至于如何才能不同步,也就是異常的現(xiàn)象,

你可以把a(bǔ)dd方法的這個(gè)synchronized關(guān)鍵字去掉之后,把次數(shù)調(diào)小一點(diǎn)改成3次,sum的初始值給設(shè)置成0.你再試試代碼,

就會(huì)發(fā)現(xiàn)所謂的不同步現(xiàn)象。

上圖的右邊就是不同步的結(jié)果,2個(gè)人每次存100,存三次,總數(shù)是不是得,100,200,300,400,500,600.得長(zhǎng)。

但是,運(yùn)行結(jié)果卻不是的,

這個(gè)時(shí)候,你再把synchronized給add方法加上去,就會(huì)出現(xiàn)左邊的圖的結(jié)果,這個(gè)就是正確的結(jié)果。

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

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

我就簡(jiǎn)單記錄下代碼。用的時(shí)候,可以分分鐘就拿出來(lái)。

總結(jié)

以上就是本文關(guān)于以銀行取錢(qián)為例模擬Java多線程同步問(wèn)題完整代碼的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

java多線程編程實(shí)例

Java多線程定時(shí)器Timer原理及實(shí)現(xiàn)

Java通過(guò)賣(mài)票理解多線程

如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • jpa多條件查詢重寫(xiě)Specification的toPredicate方法

    jpa多條件查詢重寫(xiě)Specification的toPredicate方法

    這篇文章主要介紹了多條件查詢重寫(xiě)Specification的toPredicate方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • EL調(diào)用Java方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    EL調(diào)用Java方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    簡(jiǎn)單來(lái)說(shuō),我們?cè)谝粋€(gè)類中的某個(gè)方法,可以使用EL進(jìn)行調(diào)用,這個(gè)能被EL表達(dá)式調(diào)用的方法稱之為EL函數(shù),但是這種方式必須滿足兩點(diǎn)要求,具體哪兩點(diǎn),大家可以參考下本文
    2017-07-07
  • IDEA自動(dòng)生成類圖和時(shí)序圖的操作指南

    IDEA自動(dòng)生成類圖和時(shí)序圖的操作指南

    idea 的強(qiáng)大之處在于此,它包含了很多小插件,我們不需要再次下載相關(guān)插件,只需要在idea中小小的設(shè)置一下就可以了,本文我介紹了IDEA自動(dòng)生成類圖和時(shí)序圖的操作指南,我用的是idea2020版本,需要的朋友可以參考下
    2024-05-05
  • Spring Boot基礎(chǔ)入門(mén)之基于注解的Mybatis

    Spring Boot基礎(chǔ)入門(mén)之基于注解的Mybatis

    這篇文章主要給大家介紹了關(guān)于Spring Boot基礎(chǔ)入門(mén)之基于注解的Mybatis的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例

    SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例

    這篇文章主要介紹了SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 如何使用Guava Cache做緩存

    如何使用Guava Cache做緩存

    Cache在ConcurrentHashMap的基礎(chǔ)上提供了自動(dòng)加載數(shù)據(jù)、清除數(shù)據(jù)、get-if-absend-compute的功能,本文給大家介紹如何使用Guava Cache做緩存,感興趣的朋友一起看看吧
    2023-11-11
  • MyBatis中的連接池及事物控制配置過(guò)程

    MyBatis中的連接池及事物控制配置過(guò)程

    連接池就是用于存儲(chǔ)數(shù)據(jù)庫(kù)連接的一個(gè)容器,容器其實(shí)就是一個(gè)集合對(duì)象,本文給大家介紹MyBatis中的連接池以及事物控制的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-05-05
  • 實(shí)例解讀Ajax與servlet交互的方法

    實(shí)例解讀Ajax與servlet交互的方法

    這篇文章主要介紹了Ajax與servlet交互的方法,需要的朋友可以參考下
    2014-07-07
  • Spring實(shí)現(xiàn)動(dòng)態(tài)切換多數(shù)據(jù)源的解決方案

    Spring實(shí)現(xiàn)動(dòng)態(tài)切換多數(shù)據(jù)源的解決方案

    這篇文章主要給大家介紹了Spring實(shí)現(xiàn)動(dòng)態(tài)切換多數(shù)據(jù)源的解決方案,文中給出了詳細(xì)的介紹和示例代碼,相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。
    2017-01-01
  • Java Serializable和Parcelable詳解及實(shí)例代碼

    Java Serializable和Parcelable詳解及實(shí)例代碼

    這篇文章主要介紹了Java Serializable和Parcelable詳解,并附實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-09-09

最新評(píng)論