假设车库有三个车位可以停车,使用 boolean[] 数组来表示车库,写一个程序模拟多个用户开车离开、停车入库的效果。注意:车位有车的时候不能停车。
首先,分析这是个多线程的问题,多线程的对象是停车与开车。
其次,有没有涉及到共享的数据。有,boolean[] 数组表示的车位。
最后,有没有涉及到线程的通信问题。有,当车满了的时候,要让停车线程等待。车空的时候要让开车线程等待。
以下是我实现的代码:
class parkingLot{//停车场作为一个类,其中包括各种方法以及车位的boolean[] 数组
boolean[] sites = {true,true,true};//true表示可以停车(车位空)
private boolean isFull(){//判断车位是否停满
int e=0;
for(int i=0;i<3;i++){
if(!sites[i])
e++;
}
return e==3;
}
private boolean isEmpty(){//判断车位是否全空
int e=0;
for (int i = 0; i < 3; i++) {
if(sites[i])
e++;
}
return e==3;
}
private int whichIsEmpty(){//判断哪个车位是空的,我认为也可以实现随机停车的效果,只需要使用Math类下的随机数方法
for(int i=0;i<3;i++)
if(sites[i])
return i;
return -1; //这个return其实没用,但是如果没有的话会报错
}
private int whichIsFull(){//判断哪个是车位不是空的,我认为也可以实现随机开车的效果,只需要使用Math类下的随机数方法
for(int i=0;i<3;i++)
if(!sites[i])
return i;
return -1; //这个return其实没用,但是如果没有的话会报错
}
public synchronized void park(){//停车的同步方法,先判断是否全满,若是,则线程等待
if(isFull()){
try {
System.out.println("车满了!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
int num = whichIsEmpty();
System.out.println("++++++++"+Thread.currentThread().getName() + "停在了" + num + "车位"+"++++++++");
sites[num] = false;
notifyAll();
}
}
public synchronized void drive(){//开车的同步方法,先判断是否全空,若是,则线程等待
if(isEmpty()){
try {
System.out.println("车位空了!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
int num = whichIsFull();
System.out.println("--------"+Thread.currentThread().getName()+"开走了停在"+num+"的车位"+"--------");
sites[num] = true;
notifyAll();
}
}
}
class park implements Runnable{//停车的Runnable实现类
private parkingLot pl;
public park(parkingLot pl){
this.pl = pl;
}
@Override
public void run() {
while(true){
try {
Thread.currentThread().sleep(1000);//我搞的四个停车线程,为了方便观看效果,故暂停片刻
} catch (InterruptedException e) {
e.printStackTrace();
}
pl.park();
}
}
}
class drive implements Runnable{//开车的Runnable实现类
private parkingLot pl;
public drive(parkingLot pl){
this.pl = pl;
}
@Override
public void run() {
while(true){
try {
Thread.currentThread().sleep(250);//四分之一的停车暂停时间,有更好的观看效果
} catch (InterruptedException e) {
e.printStackTrace();
}
pl.drive();
}
}
}
public class parkcar{
public static void main(String[] args){
parkingLot pl = new parkingLot();
park p=new park(pl);
drive d=new drive(pl);
Thread t1=new Thread(p,"小轿车");
Thread t2=new Thread(p,"自行车");
Thread t3=new Thread(p,"大货车");
Thread t4=new Thread(p,"摩托车");
Thread t5=new Thread(d,"车主");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
以下是结果:车位空了!
++++++++自行车停在了0车位++++++++
++++++++摩托车停在了1车位++++++++
++++++++大货车停在了2车位++++++++
车满了!
——–车主开走了停在0的车位——–
——–车主开走了停在1的车位——–
——–车主开走了停在2的车位——–
++++++++大货车停在了0车位++++++++
++++++++摩托车停在了1车位++++++++
++++++++自行车停在了2车位++++++++
——–车主开走了停在0的车位——–
++++++++小轿车停在了0车位++++++++
——–车主开走了停在0的车位——–
——–车主开走了停在1的车位——–
——–车主开走了停在2的车位——–
++++++++大货车停在了0车位++++++++
++++++++自行车停在了1车位++++++++
++++++++摩托车停在了2车位++++++++
——–车主开走了停在0的车位——–
++++++++小轿车停在了0车位++++++++
——–车主开走了停在0的车位——–
——–车主开走了停在1的车位——–
——–车主开走了停在2的车位——–
++++++++摩托车停在了0车位++++++++
++++++++大货车停在了1车位++++++++
++++++++自行车停在了2车位++++++++
感想:先分析问题,构思好要创建多少个类,需要什么方法。
搞清楚wait(),notify(),等线程通信的方法该怎么用,wait()与sleep()抛出的都是InterruptedException异常,要记得加try catch块。
ps:IDE工具就是比记事本爽,但是有时候也会让你忽略一些细节,导致脱离IDE工具以后不能像之前一样编程。
更新,稍微改动的随机版,用了hashmap存储车位的信息,然后用一个方法返回随机数。
import java.util.HashMap;
import java.util.Map;
class parkingLot{
boolean[] sites = {true,true,true};
Map<Integer, String> map = new HashMap<>();
private int getPos(){
float ran = (float) Math.random() * 2;
int pos = Math.round(ran);
return pos;
}
private boolean isFull(){
int e=0;
for(int i=0;i<3;i++){
if(!sites[i])
e++;
}
return e==3;
}
private boolean isEmpty(){
int e=0;
for (int i = 0; i < 3; i++) {
if(sites[i])
e++;
}
return e==3;
}
private int whichIsEmpty(){
/* for(int i=0;i<3;i++)
if(sites[i])
return i;
return -1; */
while(true){
int pos = getPos();
if(sites[pos])
return pos;
}
}
private int whichIsFull(){
/* for(int i=0;i<3;i++)
if(!sites[i])
return i;
return -1; */
while(true){
int pos=getPos();
if(!sites[pos])
return pos;
}
}
public synchronized void park(){
if(isFull()){
try {
System.out.println("车满了!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
int num = whichIsEmpty();
System.out.println("++++++++"+Thread.currentThread().getName() + "停在了" + num + "车位"+"++++++++");
map.put(num,Thread.currentThread().getName());
sites[num] = false;
notifyAll();
}
}
public synchronized void drive(){
if(isEmpty()){
try {
System.out.println("车位空了!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
int num = whichIsFull();
System.out.println("--------"+map.get(num)+"从"+num+"车位"+"开走了"+"--------");
map.remove(num);
sites[num] = true;
notifyAll();
}
}
}
class park implements Runnable{
private parkingLot pl;
public park(parkingLot pl){
this.pl = pl;
}
@Override
public void run() {
while(true){
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pl.park();
}
}
}
class drive implements Runnable{
private parkingLot pl;
public drive(parkingLot pl){
this.pl = pl;
}
@Override
public void run() {
while(true){
try {
Thread.currentThread().sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
pl.drive();
}
}
}
public class parkcar{
public static void main(String[] args){
parkingLot pl = new parkingLot();
park p=new park(pl);
drive d=new drive(pl);
Thread t1=new Thread(p,"小轿车");
Thread t2=new Thread(p,"自行车");
Thread t3=new Thread(p,"大货车");
Thread t4=new Thread(p,"摩托车");
Thread t5=new Thread(d,"车主");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
效果如下:车位空了!
++++++++摩托车停在了2车位++++++++
++++++++小轿车停在了0车位++++++++
++++++++大货车停在了1车位++++++++
车满了!
——–大货车从1车位开走了——–
——–小轿车从0车位开走了——–
——–摩托车从2车位开走了——–
++++++++大货车停在了1车位++++++++
++++++++小轿车停在了0车位++++++++
++++++++摩托车停在了2车位++++++++
——–小轿车从0车位开走了——–
++++++++自行车停在了0车位++++++++
——–自行车从0车位开走了——–
——–大货车从1车位开走了——–
——–摩托车从2车位开走了——–
++++++++摩托车停在了2车位++++++++
++++++++小轿车停在了0车位++++++++
++++++++大货车停在了1车位++++++++
——–大货车从1车位开走了——–
++++++++自行车停在了1车位++++++++
——–自行车从1车位开走了——–
——–摩托车从2车位开走了——–
——–小轿车从0车位开走了——–
++++++++大货车停在了2车位++++++++
++++++++摩托车停在了0车位++++++++
++++++++小轿车停在了1车位++++++++
——–小轿车从1车位开走了——–
++++++++自行车停在了1车位++++++++
——–自行车从1车位开走了——–
——–摩托车从0车位开走了——–
——–大货车从2车位开走了——–
++++++++大货车停在了2车位++++++++
++++++++小轿车停在了0车位++++++++
++++++++摩托车停在了1车位++++++++
——–摩托车从1车位开走了——–
++++++++自行车停在了1车位++++++++
——–大货车从2车位开走了——–
——–小轿车从0车位开走了——–
——–自行车从1车位开走了——–
++++++++小轿车停在了2车位++++++++
++++++++大货车停在了0车位++++++++
++++++++摩托车停在了1车位++++++++
——–大货车从0车位开走了——–
++++++++自行车停在了0车位++++++++
——–小轿车从2车位开走了——–
——–摩托车从1车位开走了——–
——–自行车从0车位开走了——–
++++++++大货车停在了0车位++++++++
++++++++小轿车停在了2车位++++++++
++++++++摩托车停在了1车位++++++++
——–摩托车从1车位开走了——–
++++++++自行车停在了1车位++++++++
——–自行车从1车位开走了——–
——–小轿车从2车位开走了——–
——–大货车从0车位开走了——–
++++++++大货车停在了1车位++++++++
++++++++小轿车停在了2车位++++++++
++++++++摩托车停在了0车位++++++++