import?java.util.HashMap;
import?java.util.Map;
public?class?Test5?{
public?static?void?main(String?args[])?{
Test5?s?=?new?Test5();
s.initStep();
}
Map<String,?String>?map;
public?Test5()?{
this.map?=?new?HashMap<String,?String>();
this.map.put("STEP_NO",?0?+?"");//?這個變量在分配時需要考慮線程安全
this.map.put("STEP_NAME",?"A");
this.map.put("THREAD_DATA",?1?+?"");
}
/**
?*?給二個步驟的線程分編號,這個是最主要的。
?*?
?*?@return
?*/
public?int?getStepNo(String?stepName)?{
int?no?=?0;
while?(true)?{
this.forSleep();
synchronized?(Test5.class)?{
String?name?=?this.map.get("STEP_NAME");
if?(name.equals(stepName))?{
if?("A".equals(stepName))?{
this.map.put("STEP_NAME",?"B");
}?else?{
this.map.put("STEP_NAME",?"A");
}
//?這裏在分配的時候壹定要鎖住,線程***享問題
String?s?=?this.map.get("STEP_NO");
no?=?Integer.parseInt(s);
no?=?no?+?1;
this.map.put("STEP_NO",?no?+?"");
break;
}
}
}
return?no;
}
public?void?forSleep()?{
try?{
Thread.sleep(1000);
}?catch?(Exception?e)?{
e.printStackTrace();
}
}
public?void?stepARunning()?{
int?no?=?this.getStepNo("A");
System.out.println("-----A步驟------線程:"?+?no?+?",編號分配成功-----------");
while?(true)?{
this.forSleep();
String?data?=?this.map.get("THREAD_DATA");
int?num?=?Integer.parseInt(data);
if?(num?==?no)?{
this.map.put("THREAD_DATA",?(num?+?1)?+?"");
break;
}
}
System.out.println("------A步驟-----線程:"?+?no?+?",執行結束-----------");
}
public?void?stepBRunning()?{
int?no?=?this.getStepNo("B");
System.out.println("-----B步驟------線程:"?+?no?+?",編號分配成功-----------");
while?(true)?{
this.forSleep();
String?data?=?this.map.get("THREAD_DATA");
int?num?=?Integer.parseInt(data);
if?(num?==?no)?{
this.map.put("THREAD_DATA",?(num?+?1)?+?"");
break;
}
}
System.out.println("------B步驟-----線程:"?+?no?+?",執行結束-----------");
}
public?void?runStepA()?{
for?(int?i?=?0;?i?<?10;?i++)?{
Thread?t1?=?new?Thread(new?Runnable()?{
public?void?run()?{
try?{
stepARunning();
}?catch?(Exception?e)?{
}
}
});
t1.start();
}
}
public?void?runStepB()?{
for?(int?i?=?0;?i?<?10;?i++)?{
Thread?t1?=?new?Thread(new?Runnable()?{
public?void?run()?{
try?{
stepBRunning();
}?catch?(Exception?e)?{
}
}
});
t1.start();
}
}
/**
?*?初始化兩個步驟
?*/
public?void?initStep()?{
Thread?t1?=?new?Thread(new?Runnable()?{
public?void?run()?{
try?{
runStepA();
}?catch?(Exception?e)?{
}
}
});
t1.start();
Thread?t2?=?new?Thread(new?Runnable()?{
public?void?run()?{
try?{
runStepB();
}?catch?(Exception?e)?{
}
}
});
t2.start();
}
}
運行結果
-----A步驟------線程:1,編號分配成功-----------
-----B步驟------線程:2,編號分配成功-----------
-----A步驟------線程:3,編號分配成功-----------
-----B步驟------線程:4,編號分配成功-----------
-----A步驟------線程:7,編號分配成功-----------
-----B步驟------線程:6,編號分配成功-----------
-----A步驟------線程:5,編號分配成功-----------
-----B步驟------線程:8,編號分配成功-----------
-----A步驟------線程:9,編號分配成功-----------
------A步驟-----線程:1,執行結束-----------
------B步驟-----線程:2,執行結束-----------
------A步驟-----線程:3,執行結束-----------
-----B步驟------線程:10,編號分配成功-----------
-----A步驟------線程:11,編號分配成功-----------
-----B步驟------線程:12,編號分配成功-----------
------B步驟-----線程:4,執行結束-----------
-----A步驟------線程:13,編號分配成功-----------
------A步驟-----線程:5,執行結束-----------
-----B步驟------線程:14,編號分配成功-----------
-----A步驟------線程:15,編號分配成功-----------
------B步驟-----線程:6,執行結束-----------
-----B步驟------線程:16,編號分配成功-----------
-----A步驟------線程:17,編號分配成功-----------
------A步驟-----線程:7,執行結束-----------
------B步驟-----線程:8,執行結束-----------
------A步驟-----線程:9,執行結束-----------
-----B步驟------線程:18,編號分配成功-----------
------B步驟-----線程:10,執行結束-----------
-----A步驟------線程:19,編號分配成功-----------
-----B步驟------線程:20,編號分配成功-----------
------A步驟-----線程:11,執行結束-----------
------B步驟-----線程:12,執行結束-----------
------A步驟-----線程:13,執行結束-----------
------B步驟-----線程:14,執行結束-----------
------A步驟-----線程:15,執行結束-----------
------B步驟-----線程:16,執行結束-----------
------A步驟-----線程:17,執行結束-----------
------B步驟-----線程:18,執行結束-----------
------A步驟-----線程:19,執行結束-----------
------B步驟-----線程:20,執行結束-----------
解析:
在保證線程安全性的前提下,給AB步驟的各個線程分配編號。然後在無限循環中等待,各自線程執行的步驟。運行結果可以看出,分配編號和執行順序是並行的,而執行結果則是AB步驟交叉執行,這個應該可以滿足妳的需求。
這是java代碼