線程在執(zhí)行的過程中,有可能會需要共享資源或者交換數(shù)據(jù),則稱這一組線程為交互線程。 線程間的交互存在兩種關(guān)系:競爭和協(xié)作。 競爭關(guān)系是指,兩個線程同時使用同一個資源時,會產(chǎn)生競爭。此時,由于線程的并發(fā)執(zhí)行,可能會產(chǎn)生與時間有關(guān)的錯誤。 如以下例題: 本例題是模擬銀行的賬戶,存款和取款均為線程,對不同賬戶的操作不會產(chǎn)生問題,但如果是對同一個賬戶同時存款和取款時,可能會發(fā)生錯誤,其代碼如下: public class Account {//賬戶類 String name; double money; public Account() { name=null; money=0; } public Account(String name,double money) { this.set(name,money); } public void set(String name,double money) { this.name=name; this.money=money; } public String get_name() { return name; } public double get_money() { return money; } public void quqian(double money) {//取錢 if(money<0) ; if(this.money>money) this.money=this.money-money; else System.out.println("您的賬戶余額不足"); } public void cunqian(double money) {//存錢 if(money>0) this.money+=money; } public String toString() { return"賬戶名:"+this.name+",賬戶中有:"+this.money; } } class exa{ public static void main(String args[]) { Account count=new Account("張三",300); System.out.println(count); SaveMoney save=new SaveMoney(count,100); SaveMoney save1=new SaveMoney(count,100); save.start(); save1.start(); getMoney get=new getMoney(count,100); get.start(); } } public class SaveMoney extends Thread{//存錢類,繼承自線程類 private Account account; private doublevalue; public SaveMoney(Account a,double v) { this.account=a; this.value=v; } public void run() { this.account.cunqian(value); System.out.println("存入"+value+"后,您的賬戶余額為:"+this.account.money); } } public class getMoney extends Thread{//取錢類,繼承自線程類 private Account account; private doublevalue; public getMoney(Account a,double v) { this.account=a; this.value=v; } public void run() { this.account.quqian(value); System.out.println("取出"+value+"后,您的賬戶余額為:"+this.account.money); } } 其運行結(jié)果如下: 從這個結(jié)果會發(fā)現(xiàn),“張三”這個賬戶中原有300元,在存入100元之后卻變成了500元,這個結(jié)果明顯不是我們想要的結(jié)果,產(chǎn)生這個錯誤的原因就在于,存錢線程有兩個,取錢線程有一個,都是對賬戶“張三”在進(jìn)行操作,由于線程的并發(fā)執(zhí)行,在兩個存錢線程有可能是同時執(zhí)行的,所以它的結(jié)果會變?yōu)?00,但這個結(jié)果是錯誤的。 要解決這個錯誤,需要互斥。 下一篇會介紹線程的互斥。 |
|