[線程組概念]
線程是可以被組織的,java中存在線程組的概念,每個(gè)線程都是一個(gè)線程組的成員,線程組把多個(gè)線程集成為一個(gè)對象,通過線程組可以同時(shí)對其中的多個(gè)線程進(jìn)行操作,如啟動一個(gè)線程組的所有線程等.Java的線程組由java.lang包中的Thread——Group類實(shí)現(xiàn).
ThreadGroup類用來管理一組線程,包括:線程的數(shù)目,線程間的關(guān)系,線程正在執(zhí)行的操作,以及線程將要啟動或終止時(shí)間等.線程組還可以包含線程組.在Java的應(yīng)用程序中,最高層的線程組是名位main的線程組,在main中還可以加入線程或線程組,在mian的子線程組中也可以加入線程和線程組,形成線程組和線程之間的樹狀繼承關(guān)系。像上面創(chuàng)建的線程都是屬于main這個(gè)線程組的。
借用上面的例子,main里面可以這樣寫:
public static void main(String[] args)
{
/***************************************
ThreadGroup(String name)
ThreadGroup(ThreadGroup parent, String name)
***********************************/
ThreadGroup group1=new ThreadGroup("group1");
ThreadGroup group2=new ThreadGroup(group1,"group2");
Thread t1=new Thread(group2,new MyThread());
Thread t2=new Thread(group2,new MyThread());
Thread t3=new Thread(group2,new MyThread());
t1.start();
t2.start();
t3.start();
}
線程組的嵌套,t1,t2,t3被加入group2,group2加入group1。
另外一個(gè)比較多就是關(guān)于線程同步方面的,試想這樣一種情況,你有一筆存款在銀行,你在一家銀行為你的賬戶存款,而你的妻子在另一家銀行從這個(gè)賬戶提款,現(xiàn)在你有1000塊在你的賬戶里面。你存入了1000,但是由于另一方也在對這筆存款進(jìn)行操作,人家開始執(zhí)行的時(shí)候只看到賬戶里面原來的1000元,當(dāng)你的妻子提款1000元后,你妻子所在的銀行就認(rèn)為你的賬戶里面沒有錢了,而你所在的銀行卻認(rèn)為你還有2000元。
看看下面的例子:
class BlankSaving //儲蓄賬戶
{
private static int money=10000;
public void add(int i)
{
money=money+i;
System.out.println("Husband 向銀行存入了 [¥"+i+"]");
}
public void get(int i)
{
money=money-i;
System.out.println("Wife 向銀行取走了 [¥"+i+"]");
if(money<0)
System.out.println("余額不足!");
}
public int showMoney()
{
return money;
}
}
class Operater implements Runnable
{
String name;
BlankSaving bs;
public Operater(BlankSaving b,String s)
{
name=s;
bs=b;
}
public static void oper(String name,BlankSaving bs)
{
if(name.equals("husband"))
{
try
{
for(int i=0;i<10;i++)
{
Thread.currentThread().sleep((int)(Math.random()*300));
bs.add(1000);
}
}catch(InterruptedException e){}
}else
{
try
{
for(int i=0;i<10;i++)
{
Thread.currentThread().sleep((int)(Math.random()*300));
bs.get(1000);
}
}catch(InterruptedException e){}
}
}
public void run()
{
oper(name,bs);
}
}
public class BankTest
{
public static void main(String[] args)throws InterruptedException
{
BlankSaving bs=new BlankSaving();
Operater o1=new Operater(bs,"husband");
Operater o2=new Operater(bs,"wife");
Thread t1=new Thread(o1);
Thread t2=new Thread(o2);
t1.start();
t2.start();
Thread.currentThread().sleep(500);
}
}
下面是其中一次的執(zhí)行結(jié)果:
---------first--------------
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Husband 向銀行存入了 [¥1000]
看到了嗎,這可不是正確的需求,在husband還沒有結(jié)束操作的時(shí)候,wife就插了進(jìn)來,這樣很可能導(dǎo)致意外的結(jié)果。解決辦法很簡單,就是將對數(shù)據(jù)進(jìn)行操作方法聲明為synchronized,當(dāng)方法被該關(guān)鍵字聲明后,也就意味著,如果這個(gè)數(shù)據(jù)被加鎖,只有一個(gè)對象得到這個(gè)數(shù)據(jù)的鎖的時(shí)候該對象才能對這個(gè)數(shù)據(jù)進(jìn)行操作。也就是當(dāng)你存款的時(shí)候,這筆賬戶在其他地方是不能進(jìn)行操作的,只有你存款完畢,銀行管理人員將賬戶解鎖,其他人才能對這個(gè)賬戶進(jìn)行操作。
修改public static void oper(String name,BlankSaving bs)為public static void oper(String name,BlankSaving bs),再看看結(jié)果:
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Husband 向銀行存入了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
Wife 向銀行取走了 [¥1000]
當(dāng)丈夫完成操作后,妻子才開始執(zhí)行操作,這樣的話,對共享對象的操作就不會有問題了。
相關(guān)推薦:計(jì)算機(jī)等級考試二級Java經(jīng)典算法大全匯總北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |