模擬四臺電梯的工作狀態
package 電梯03;
/* synchronized機制
* 當一個對象被多個線程訪問時,爲防止數據的破壞,只能每次允許一個線程進行操作,這樣才能保證數據的統一性,所以就有了鎖
* 當一個線程在佔用鎖時,其他線程只能一直等待,等待鎖被釋放 釋放之後 其他線程會競爭來獲取鎖,然後進行數據操作
* 多線程協作的問題:
* 線程t1,t11,t12,t13表示臺電梯獨立運行:
* <span style="white-space:pre"> </span>每臺電梯的運行都牽涉到 實際的人數 所以就需要對這個實際變動的人數進行加鎖(synchronized) 鎖的添加是需要的時候添加(多線程狀態下能,
* 多個線程可能同時操作同一個數據的地方),這些地方都需要加鎖才能保證數據的統一性 才能保證數據被正在操作的同時不被其它方法操作。
* 線程tal:用來計算和檢測每層樓等待的人數和電梯經過每層樓時電梯內的人數
* <span style="white-space:pre"> </span>計算的完成也是通過鏈表LinkList來實現的,然而LinkList加了鎖 所以會並不會發生衝突
* 線程tl:來實現對各種log日誌的輸出和保存
* <span style="white-space:pre"> </span>通過setStr()方法把傳來的輸出日誌(str)保存到隊列之後就會釋放當前鎖,並通知weit()所在的鎖 可以繼續執行了
* 然後就會寫入到txt文件中
*
* 當四臺電梯的線程一起走到setStr()方法之前時,以誰先獲得setStr()鎖爲準,然後誰先獲得誰就會在隊列中先寫入文件
*/
/* 單線程電梯(1臺電梯運行,10層)模擬:
* Stack 表示電梯所能裝載的人數
* 下面兩個鏈表表示每層樓對應的人 0未啓用
* LinkList[] up = new LinkList[11]; want=1 向上去的人所在隊列
LinkList[] down = new LinkList[11]; want=-1 向下去的人所在隊列
Cus 乘客:
at:所在層數
to:目的層數
want:1表示向上去,-1表示向下去
key:乘客編號
*/
public class Test {
public static void main(String[] args){
LinkList[] up = new LinkList[11];
LinkList[] down = new LinkList[11];
for(int k=0;k<11;k++){//對每個鏈表進行初始化
up[k]=new LinkList();
down[k]=new LinkList();
}
//STACKNod s = new STACKNod();
String path = "F:/Log/Log.txt";
Log log = new Log(path);
Thread tl = new Thread(log);
tl.start();
Stack st = new Stack();
Work wokk = new Work(st,up,down,log);
Thread t1 = new Thread(wokk);
t1.start();
Stack st1 = new Stack();
Work wokk1 = new Work(st1,up,down,log);
Thread t11 = new Thread(wokk1);
t11.start();
Stack st2 = new Stack();
Work wokk2 = new Work(st2,up,down,log);
Thread t12 = new Thread(wokk2);
t12.start();
Stack st3 = new Stack();
Work wokk3 = new Work(st3,up,down,log);
Thread t13 = new Thread(wokk3);
t13.start();
Total total = new Total(st,up,down,log);
Thread tal = new Thread(total);
tal.start();
/*
Log log1 = new Log(wokk1);
Thread tl1 = new Thread(log1);
tl1.start();
Log log2 = new Log(wokk2);
Thread tl2 = new Thread(log2);
tl2.start();
Log log3 = new Log(wokk3);
Thread tl3 = new Thread(log3);
tl3.start();
*/
Cus[] cus=new Cus[100000];
for(int i=0;i<10;i++){
while(true){
int a=(int)(Math.random()*10+1);
int t=(int)(Math.random()*10+1);
if(a<t&&t!=0&&a!=0){
cus[i] = new Cus(a,t,i,1);
up[a].add(cus[i]);
break;
}else if(a>t&&t!=0&&a!=0){
cus[i] = new Cus(a,t,i,-1);
down[a].add(cus[i]);
break;
}
}
//wokk.sleep();
}
}
}
class Work implements Runnable{
int work=0;
int stay;
Stack dt;//=new Stack();
boolean asd=true;
LinkList[] up;
LinkList[] down;
volatile String str;
Log log;
public String getStr(){
return str;
}
public Work(Stack s, LinkList[] u,LinkList[] d, Log lo){
up=u;
down=d;
stay=1;
dt=s;
log=lo;
}
public void run(){
while(true){
if(work==0){//無人狀態
if(asd==false){
// System.out.println(Thread.currentThread().getId() +" " + "電梯 暫停在"+stay+"樓");
str=new String(Thread.currentThread().getId() +" " + "電梯 暫停在"+stay+"樓");
log.setStr(str);
// sss.push(str);
sleep();
}else{
if(up!=null){
work=1;
}else if(down!=null){
work=-1;
}else{
sleep();
}
}
}else if(work==1){//向上工作狀態
sleep();
// System.out.println(Thread.currentThread().getId() +" " + "電梯到達"+stay+"樓--[上]");
str=new String(Thread.currentThread().getId() +" " + "電梯到達"+stay+"樓--[上]");
log.setStr(str);
// sss.push(str);
up_out(stay);//每到達一層檢查是否有人--出
if(up[stay].getHeadNode()!=null){
up_in(stay);//每到達一層檢查是否有人--上
}
if(dt.isEmpty()&&isK(up)&&isK(down)){//當電梯內無人 且沒人使用電梯時暫停,繼續等待
asd=false;
work=0;
stay--;
}
if(dt.isEmpty()&&downyouren(stay)){//將上樓的人運輸完之後,檢查當前樓層上方是否有人下,若有人下 則去接人,若無人下則電梯下樓
// System.out.println(Thread.currentThread().getId() +" " + "電梯 暫停在"+stay+"------->樓");
str=new String(Thread.currentThread().getId() +" " + "電梯 暫停在"+stay+"------->樓");
log.setStr(str);
// sss.push(str);
down_in(stay);
down_out(stay);
//up_in(stay);
//up_out(stay);
}
stay++;
if(stay>10){
work=-1;
stay=10;
}
}else if(work==-1){//向下工作狀態
sleep();
// System.out.println(Thread.currentThread().getId() +" " + "電梯到達"+stay+"樓--[下]");
str=new String(Thread.currentThread().getId() +" " + "電梯到達"+stay+"樓--[下]");
log.setStr(str);
// sss.push(str);
down_out(stay);
if(down[stay].getHeadNode()!=null){
down_in(stay);
}
if(dt.isEmpty()&&isK(up)&&isK(down)){
asd=false;
work=0;
stay++;
}
if(dt.isEmpty()&&upyouren(stay)){
// System.out.println(Thread.currentThread().getId() +" " + "電梯 暫停在"+stay+"------->樓");
str=new String(Thread.currentThread().getId() +" " + "電梯 暫停在"+stay+"------->樓");
log.setStr(str);
// sss.push(str);
up_in(stay);
up_out(stay);
//down_in(stay);
//down_out(stay);
}
stay--;
if(stay<1){
work=1;
stay=1;
}
}
}
}
public boolean upyouren(int s){
for(int i=s;i<=10;i++){
if(up[i].getHeadNode()!=null){
return true;
}
if(down[i].getHeadNode()!=null){
return true;
}
}
return false;
}
public void down_add(int s){
for(int i=s;i>=1;i--){
up_in(i);
up_out(i);
down_in(i);
down_out(i);
}
}
public boolean downyouren(int s){
for(int i=s;i>=1;i--){
if(down[i].getHeadNode()!=null){
return true;
}
if(up[i].getHeadNode()!=null){
return true;
}
}
return false;
}
public boolean isK(LinkList[] arr){
for(int i=1;i<=10;i++){
if(arr[i].getHeadNode()!=null){
return false;
}
}
return true;
}
public boolean isKU(int s){
for(int i=s;i<=10;i++){
if(down[i].getHeadNode()!=null){
return true;
}
if(up[i].getHeadNode()!=null){
return true;
}
}
return false;
}
public boolean isKD(int s){
for(int i=s;i>=1;i--){
if(down[i].getHeadNode()!=null){
return true;
}
if(up[i].getHeadNode()!=null){
return true;
}
}
return false;
}
public void up_in(int i){
if(up[i].getHeadNode()!=null){
Node temp=up[i].getHeadNode();
while(temp!=null){
if(dt.getTop()<10){
// System.out.println(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getAt()+"-to-"+temp.cus.getTo()+"樓---【上樓--進電梯】");
str=new String(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getAt()+"-to-"+temp.cus.getTo()+"樓---【上樓--進電梯】");
log.setStr(str);
// sss.push(str);
dt.push(temp.cus);
up[i].del(temp.cus);
}else{
// System.out.println(Thread.currentThread().getId() +" " + "電梯已上滿!");
str=new String(Thread.currentThread().getId() +" " + "電梯已上滿!");
log.setStr(str);
// sss.push(str);
}
temp=temp.n;
}
}else{
}
}
public void up_out(int i){
if(dt.getTop()>0){
Node temp = dt.ll.getHeadNode();
while(temp!=null){
if(temp.cus.getTo()==i){
// System.out.println(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getAt()+"-to-"+temp.cus.getTo()+"樓---【已下樓--出電梯】");
str= new String(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getAt()+"-to-"+temp.cus.getTo()+"樓---【已下樓--出電梯】");
log.setStr(str);
// sss.push(str);
dt.pop(temp.cus);
}
temp=temp.n;
}
}
}
public void down_in(int i){
if(down[i].getHeadNode()!=null){
Node temp=down[i].getHeadNode();
while(temp!=null){
if(dt.getTop()<10){
// System.out.println(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getAt()+"-to-"+temp.cus.getTo()+"樓---【下樓--進電梯】");
str=new String(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getAt()+"-to-"+temp.cus.getTo()+"樓---【下樓--進電梯】");
log.setStr(str);
// sss.push(str);
dt.push(temp.cus);
down[i].del(temp.cus);
}else{
// System.out.println(Thread.currentThread().getId() +" " + "電梯已上滿!");
str = new String(Thread.currentThread().getId() +" " + "電梯已上滿!");
log.setStr(str);
// sss.push(str);
}
temp=temp.n;
}
}
}
public void down_out(int i){
if(dt.getTop()>0){
Node temp = dt.ll.getHeadNode();
while(temp!=null){
if(temp.cus.getTo()==i){
// System.out.println(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getTo()+"-to-"+temp.cus.getTo()+"樓---【已下樓--出電梯】");
str= new String(Thread.currentThread().getId() +" " + temp.cus.getKey()+"號-at-"+temp.cus.getTo()+"-to-"+temp.cus.getTo()+"樓---【已下樓--出電梯】");
log.setStr(str);
// sss.push(str);
dt.pop(temp.cus);
}
temp=temp.n;
}
}
}
public void sleep(){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Cus{
private int at;
private int to;
private int key;
private int want;
public Cus(int a, int t, int k, int w){
at=a;
to=t;
key=k;
want=w;
}
public synchronized int getTo(){
int a=to;
return a;
}
public synchronized int getAt(){
int a=at;
return a;
}
public synchronized int getKey(){
int a=key;
return a;
}
public synchronized int getWant(){
int a=want;
return a;
}
}
class Node{
Node f;
Node n;
Cus cus;
public Node(Cus c){
f=n=null;
cus=c;
}
}
class Stack{
private int top;
LinkList ll = new LinkList();
public Stack(){
top=0;
}
public synchronized int getTop(){
int a=top;
return a;
}
public synchronized boolean isEmpty(){
if(top==0){
return true;
}
return false;
}
public synchronized void push(Cus c){
if(top<10){
top++;
ll.add(c);
}else{
System.out.println(Thread.currentThread().getId() +" " + "電梯---已滿");
}
}
public synchronized void pop(Cus c){
if(top>0){
ll.del(c);
top--;
}else{
System.out.println(Thread.currentThread().getId() +" " + "電梯---無人");
}
}
}
class LinkList{
private Node head;
private Node tail;
public LinkList(){
head=tail=null;
}
public synchronized Node getHeadNode(){
Node node=head;
return node;
}
public synchronized boolean isEmpty(){
if(head==null){
return true;
}
return false;
}
public synchronized void add(Cus c){
Node node = new Node(c);
if(head!=null){
tail.n=node;
node.f=tail;
tail=node;
tail.n=null;
}else{
head=tail=node;
head.f=tail.n=null;
}
}
public synchronized void del(Cus c){
Node node = find(c);
if(node!=null){
if(node==head){//.f==null
if(head.n==null){
head=tail=null;
}else{
head=head.n;
head.f=null;
}
}else if(node==tail){
if(tail.f==null){
head=tail=null;
}else{
tail=tail.f;
tail.n=null;
}
}else{
node.f.n=node.n;
node.n.f=node.f;
}
}
}
public synchronized int count(){
int c=0;
if(head!=null){
Node node=head;
while(node!=null){
c++;
node=node.n;
}
return c;
}
return 0;
}
public synchronized Node find(Cus c){
if(head!=null){
Node node = head;
while(node!=null){
if(node.cus.equals(c)){
return node;
}
node=node.n;
}
}
return null;
}
}
創建線程 統計每層上下樓人數
package 電梯03;
//統計數據
public class Total implements Runnable{
//以樓層爲單位逐層記錄
int at;//每層樓的人數
int total;//電梯人數
int to_up;//上樓人數
int to_down;//下樓人數
String str;
Stack st;
LinkList[] up;
LinkList[] down;
Log log;
public Total(Stack s, LinkList[] u, LinkList[] d, Log l){
st=s;
up=u;
down=d;
at=total=to_up=to_down=0;
log=l;
}
public void run(){
while(true){
try {
Thread.sleep(5000);
} catch (InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
int stay=1;
while(stay<=10){
if(up[stay].getHeadNode()!=null){
to_up=up[stay].count();
/* Node temp = up[stay].getHeadNode();
while(temp!=null){
if(temp!=null){
to_up+=1;
}
temp=temp.n;
}
*/
}
//System.out.println("第"+stay+"層【-上樓-人數】爲"+to_up);
str=new String("第"+stay+"層【-上樓-人數】爲"+to_up);
log.setStr(str);
if(down[stay].getHeadNode()!=null){
to_down=down[stay].count();
/* Node node = down[stay].getHeadNode();
while(node!=null){
if(node!=null){
to_down+=1;
}
node=node.n;
}
*/
}
//System.out.println("第"+stay+"層【-下樓-人數】爲"+to_down);
str=new String("第"+stay+"層【-下樓-人數】爲"+to_down);
log.setStr(str);
at=to_up+to_down;
//System.out.println("第"+stay+"層【-總-人數】爲"+at);
str=new String("第"+stay+"層【-總-人數】爲"+at);
log.setStr(str);
total=st.getTop();
//System.out.println("第"+stay+"層【電梯內-人數】爲"+total);
str=new String("第"+stay+"層【電梯內-人數】爲"+total);
log.setStr(str);
at=to_up=to_down=0;
stay++;
}
}
}
}
package 電梯03;
import java.io.FileWriter;
import java.io.IOException;
//輸出log 日誌 線程
public class Log implements Runnable{
//以樓層爲單位逐層輸出
STACKNod sta = new STACKNod();
FileWriter write = null;
public Log(String pat){
try {
write = new FileWriter(pat);
write.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//可追加
}
public synchronized void setStr(String st){
System.out.println(st);
sta.push(st);
notify();
}
public void run(){
while(true){
print();
}
}
public void print(){
// System.out.println(str+"00000000000000000000000000000000000000000000");
STACKNod staa= new STACKNod();
synchronized(this){
try {
wait();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(sta.getTop()>0){
staa.push(sta.pop());
}
}
try{
while(staa.getTop()>0){
String sss=staa.pop();
write.write(sss+"\r\n");
write.flush();
}
}catch(IOException e){
e.printStackTrace();
}
/*
* finally{
if(write!=null){
try {
write.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
*/
}
public synchronized void print(String s){
// System.out.println(str+"00000000000000000000000000000000000000000000");
String path = "F:/Log/Log.txt";
FileWriter write = null;
try{
write = new FileWriter(path);//可追加
write.write(s+"\r\n");;
}catch(IOException e){
e.printStackTrace();
}finally{
if(write!=null){
try {
write.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
class STACKNod{
private int top;
LinkNod ll = new LinkNod();
public STACKNod(){
top=0;
}
public int getTop(){
int a=top;
return a;
}
public boolean isEmpty(){
if(top==0){
return true;
}
return false;
}
public void push(String c){
top++;
ll.add(c);
}
public String pop(){
if(top>0){
String s=ll.del();
top--;
return s;
}
return null;
}
}
class LinkNod{
private NodNod head;
private NodNod tail;
public LinkNod(){
head=tail=null;
}
public NodNod getHeadNode(){
NodNod node=head;
return node;
}
public boolean isEmpty(){
if(head==null){
return true;
}
return false;
}
public void add(String c){
NodNod node = new NodNod(c);
if(head!=null){
tail.n=node;
node.f=tail;
tail=node;
tail.n=null;
}else{
head=tail=node;
head.f=tail.n=null;
}
}
public void del(String c){
NodNod node = find(c);
if(node!=null){
if(node==head){//.f==null
if(head.n==null){
head=tail=null;
}else{
head=head.n;
head.f=null;
}
}else if(node==tail){
if(tail.f==null){
head=tail=null;
}else{
tail=tail.f;
tail.n=null;
}
}else{
node.f.n=node.n;
node.n.f=node.f;
}
}
}
public String del(){
if(head!=null){
if(head==tail){
String s=head.str;
head=tail=null;
return s;
}else{
String s=head.str;
head=head.n;
head.f=null;
return s;
}
}
return null;
}
public NodNod find(String c){
if(head!=null){
NodNod node = head;
while(node!=null){
if(node.str.equals(c)){
return node;
}
node=node.n;
}
}
return null;
}
}
class NodNod{
NodNod f;
NodNod n;
String str;
public NodNod(String s){
f=n=null;
str=s;
}
}