文章目录
- 应用场景
- 状态机
- 结果
- github
- 参考博客
应用场景
对于有不同状态的事件可以采用状态机设计模式。比如电梯的运行,停止等等状态。
状态机
参考下面博客进行编写,以及进行优化,使用锁进行同步,不足之处多多指教~
模拟各种房间的预定,入住,退房等等…
定义状态
public interface State {
/**
* 预定
*/
public void bookRoom();
/**
* 退房
*/
public void checkOutRoom();
/**
* 入住
*/
public void checkInRoom();
}
各种状态重写
@Data
@AllArgsConstructor
public class CheckInState implements State {
Room room;
@Override
public void bookRoom() {
room.setState(room.getBookState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间预定!");
}
@Override
public void checkOutRoom() {
room.setState(room.getCheckOutState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间退房!");
}
@Override
public void checkInRoom() {
if (!(room.getState() instanceof CheckInState)) {
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间不能入住!");
return;
}
room.setState(room.getCheckInState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间入住!");
}
}
@Data
@AllArgsConstructor
public class CheckOutState implements State {
Room room;
@Override
public void bookRoom() {
room.setState(room.getBookState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间被预定!");
}
@Override
public void checkOutRoom() {
if (!(room.getState() instanceof CheckOutState)) {
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间不能退订!");
return;
}
room.setState(room.getCheckOutState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间退订!");
}
@Override
public void checkInRoom() {
room.setState(room.getCheckInState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间入住!");
}
}
@Data
@AllArgsConstructor
public class BookState implements State {
Room room;
@Override
public void bookRoom() {
if (!(room.getState() instanceof BookState)) {
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间不能预定!");
return;
}
room.setState(room.getBookState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间预定!");
}
@Override
public void checkOutRoom() {
room.setState(room.getCheckOutState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间退订!");
}
@Override
public void checkInRoom() {
room.setState(room.getCheckInState());
System.out.println(Thread.currentThread().getName()+"当前" + room.getRoomId() + "房间入住!");
}
}
房间类
@Data
public class Room {
ReentrantLock reentrantLock = new ReentrantLock();
Integer roomId;
/**
* 状态
*/
State state;
CheckInState checkInState;
CheckOutState checkOutState;
BookState bookState;
public Room(Integer roomId) {
this.roomId = roomId;
checkInState = new CheckInState(this);
checkOutState = new CheckOutState(this);
bookState = new BookState(this);
state = checkOutState;
}
/**
* 预定
*/
public void bookRoom() {
state.bookRoom();
}
/**
* 退房
*/
public void checkOutRoom() {
state.checkOutRoom();
}
/**
* 入住
*/
public void checkInRoom() {
state.checkInRoom();
}
@Override
public String toString() {
return "该房间" + roomId + "的状态是:" + getState().getClass().getName();
}
}
房间初始化
public class RoomList {
/**
* 单人间
*/
public static List<Room> list1 = new ArrayList<>(10);
/**
* 双人间
*/
public static List<Room> list2 = new ArrayList<>(10);
static {
Room room1 = new Room(1);
Room room2 = new Room(2);
Room room3 = new Room(3);
list1.add(room1);
list1.add(room2);
list1.add(room3);
Room room4 = new Room(4);
Room room5 = new Room(5);
list2.add(room4);
list2.add(room5);
}
}
测试类
public class BookTest {
public static void main(String[] args) throws InterruptedException {
//单人间
List<Room> list1 = RoomList.list1;
//双人间
List<Room> list2 = RoomList.list2;
int b = 0;
do {
b++;
new Thread(() -> {
for (Room room : list1) {
int i = 0;
if (room.getState() instanceof CheckOutState) {
room.reentrantLock.lock();
i++;
System.out.println(Thread.currentThread().getName()+"预定到房间:" + room.getRoomId());
room.setState(room.getBookState());
room.bookRoom();
room.checkInRoom();
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
room.checkOutRoom();
room.reentrantLock.unlock();
if (i == list1.size()) {
System.out.println(Thread.currentThread().getName()+"当前没有房间......");
}
}
}
}).start();
new Thread(() -> {
int i = 0;
for (Room room : list2) {
i++;
if (room.getState() instanceof CheckOutState) {
room.reentrantLock.lock();
System.out.println(Thread.currentThread().getName()+"预定到房间:" + room.getRoomId());
room.setState(room.getCheckInState());
room.checkInRoom();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
room.checkOutRoom();
room.reentrantLock.unlock();
if (i == list2.size()) {
System.out.println(Thread.currentThread().getName()+"当前没有房间......");
}
}
}
}).start();
Thread.sleep(500);
} while (b < 10);
Thread.sleep(10000);
for (Room room : list1) {
System.out.println(room.getRoomId()+" "+room.getState());
}
for (Room room : list2) {
System.out.println(room.getRoomId()+" "+room.getState());
}
}
}
结果
Thread-0预定到房间:1
Thread-1预定到房间:4
Thread-0当前1房间预定!
Thread-0当前1房间入住!
Thread-1当前4房间入住!
Thread-2预定到房间:2
Thread-3预定到房间:5
Thread-3当前5房间入住!
Thread-2当前2房间预定!
Thread-2当前2房间入住!
Thread-1当前4房间退房!
Thread-4预定到房间:3
Thread-4当前3房间预定!
Thread-4当前3房间入住!
Thread-5预定到房间:4
Thread-5当前4房间入住!
Thread-3当前5房间退房!
Thread-3当前没有房间......
Thread-7预定到房间:5
Thread-7当前5房间入住!
Thread-5当前4房间退房!
Thread-9预定到房间:4
Thread-9当前4房间入住!
Thread-7当前5房间退房!
Thread-7当前没有房间......
Thread-9当前4房间退房!
Thread-9预定到房间:5
Thread-9当前5房间入住!
Thread-13预定到房间:4
Thread-13当前4房间入住!
Thread-0当前1房间退房!
Thread-9当前5房间退房!
Thread-9当前没有房间......
Thread-13当前4房间退房!
Thread-13预定到房间:5
Thread-13当前5房间入住!
Thread-16预定到房间:1
Thread-16当前1房间预定!
Thread-16当前1房间入住!
Thread-17预定到房间:4
Thread-17当前4房间入住!
Thread-2当前2房间退房!
Thread-18预定到房间:2
Thread-18当前2房间预定!
Thread-18当前2房间入住!
Thread-4当前3房间退房!
Thread-13当前5房间退房!
Thread-13当前没有房间......
Thread-17当前4房间退房!
Thread-17预定到房间:5
Thread-17当前5房间入住!
Thread-17当前5房间退房!
Thread-17当前没有房间......
Thread-16当前1房间退房!
Thread-16预定到房间:3
Thread-16当前3房间预定!
Thread-16当前3房间入住!
Thread-18当前2房间退房!
Thread-16当前3房间退房!
1 CheckOutState(room=该房间1的状态是:com.example.demo.statepackage.CheckOutState)
2 CheckOutState(room=该房间2的状态是:com.example.demo.statepackage.CheckOutState)
3 CheckOutState(room=该房间3的状态是:com.example.demo.statepackage.CheckOutState)
4 CheckOutState(room=该房间4的状态是:com.example.demo.statepackage.CheckOutState)
5 CheckOutState(room=该房间5的状态是:com.example.demo.statepackage.CheckOutState)