模拟四台电梯的工作状态
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;
}
}