java如何避免线程耗尽
假设我有一家有m间客房的酒店
客人(线程)总是进进出出
一个房间里可以有很多人,但只有一个房间会有人。例如:
- 客人A(想要1号房间)
- 客人B(想要2号房间)
客人C(1号房间)
一旦所有房间都空了,A可以去1号房间
B还不能去2号房间,因为还有一个房间里还有人
C可以去1号房间,因为C想要的房间是里面唯一有人的房间
考虑到A和C离开1号房间,B应该可以去2号房间
最后一位离开房间的客人应该阻止其他客人(避免他们在他出来的时候进来)直到房间离开,这样其他人可以继续
我该如何实现这一点——线程不会饿死
为了简单起见,假设客人一进房间,就睡几秒钟,然后出去。以下是我(错误的)实现:
import java.util.ArrayList;
import java.util.Random;
public class Guest extends Thread {
static Rooms rooms = new Rooms(5);
int id;
Guest(int id) {
this.id = id;
}
public void run() {
rooms.join(this);
nap();
rooms.quit(this);
}
public void nap() {
try {
sleep((new Random().nextInt(4000) + 1000));
} catch (InterruptedException e) {
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20; i++) {
Thread t = new Guest(i);
t.start();
Thread.sleep((long) new Random().nextInt(1500) + 1000);
}
}
}
class Rooms {
Room[] rooms;
int busy;
Rooms(int m) {
busy = -1;
rooms = new Room[m + 1];
for (int i = 0; i < m + 1; i++)
rooms[i] = new Room();
}
void join(Guest h) {
if (busy == -1) {
busy = (new Random().nextInt(rooms.length));
}
rooms[busy].add(h);
System.out.println("Guest " + h.id + " came inside room " + busy + " with " + rooms[busy].size() + " people");
}
void quit(Guest h) {
if (rooms[busy].size() == 1) {
setHandler(busy, h);
} else {
rooms[busy].remove(h);
System.out
.println("Guest " + h.id + " came out of room " + busy + " with " + rooms[busy].size() + " people");
}
}
synchronized void setHandler(int numQuarto, Guest ultimo) {
System.out.println("(Last) Guest " + ultimo.id + " came out of room " + busy + " with "
+ rooms[numQuarto].size() + " people");
rooms[numQuarto].remove(ultimo);
busy = -1;
}
}
class Room extends ArrayList<Guest> {
}
# 1 楼答案
你不能。根据你所给予的,需要实施其他机制来保证不会发生饥饿。比如
因此,n线程有可能在整个时间内都进入房间m。也有可能,在这段时间里,更多的线程进来想要另一个房间。但是,在房间m首次清空之前,他们无法进入房间(这可能永远不会发生)。这可以在任意数量的房间和线程中继续。即使
那是因为
这意味着另一个线程可能进入一个已经被占用的房间,其中一个或多个线程还有t时间睡觉。新线程进入睡眠状态,直到上一个线程之后才会醒来。睡觉时,可能会有更多线程进入该房间,这可能会导致其他线程等待其他房间饿死