编写多线程应用程序,模拟多个人通过一个山洞,这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒。随机生成10个人,同时准备过此山洞,*显示一下每次通过山洞人的姓名。
时间: 2024-12-15 16:23:02 浏览: 22
为了编写一个多线程模拟多人通过山洞的程序,我们可以使用Python的`threading`模块来创建并管理线程。在这个例子中,我们将创建10个线程,每个线程代表一个人,并维护一个全局锁来保证任何时候只有一个线程可以进入山洞。
下面是一个简单的Python实现:
```python
import threading
import random
# 山洞的状态
tunnel = threading.Lock()
people = ['Person' + str(i) for i in range(1, 11)] # 随机生成10个人名
def pass_through_tunnel(person):
global tunnel
with tunnel:
print(f"{person} is passing through the cave.")
time.sleep(5) # 模拟5秒过洞时间
# 创建并启动10个线程
for person in people:
thread = threading.Thread(target=pass_through_tunnel, args=(person,))
thread.start()
# 等待所有线程结束
for thread in threading.enumerate():
if thread.is_alive(): # 检查线程是否还在运行
thread.join()
相关问题
编写多线程应用程序,模拟多个人通过一个山洞,这个山洞每次只能通过一个人,每个人通过山洞的时间为 5 秒。随机生成 10 个人,同时准备过此山洞,显示一下每次通过山洞人的姓名。
为了编写这样一个多线程应用程序,我们可以采用Java语言的`Thread`类和`synchronized`关键字来模拟并发控制。我们将创建一个`Cave`类作为山洞,它有一个`people`列表来存储等待过洞的人,并有一个`synchronized`方法`passThrough()`用于一个人通过山洞。
首先,我们定义一个`Person`类,包含姓名和进入山洞的标识:
```java
class Person {
private String name;
private boolean passed;
public Person(String name) {
this.name = name;
this.passed = false;
}
// getters and setters
public synchronized void passThrough(Cave cave) {
while (cave.isFull() || this.passed) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " - " + name + " is passing through the cave.");
cave.add(this);
this.passed = true;
notifyAll(); // 唤醒其他等待者
}
}
```
接着,创建`Cave`类,维护人员列表并处理同步:
```java
import java.util.ArrayList;
import java.util.List;
class Cave {
private final int capacity;
private List<Person> peopleQueue;
private final Object lock;
public Cave(int capacity) {
this.capacity = capacity;
this.peopleQueue = new ArrayList<>();
this.lock = new Object();
}
public synchronized void add(Person person) {
if (!isFull()) {
peopleQueue.add(person);
} else {
person.wait();
}
}
public synchronized boolean isFull() {
return peopleQueue.size() >= capacity;
}
public synchronized void clear() {
peopleQueue.clear();
notifyAll();
}
public synchronized void run() {
for (int i = 0; i < 10; i++) {
Person nextPerson = peopleQueue.get(0);
nextPerson.passThrough(this);
peopleQueue.remove(nextPerson);
}
this.notifyAll(); // 唤醒所有等待者
}
}
public class Main {
public static void main(String[] args) {
Cave cave = new Cave(1);
Person[] people = new Person[10];
for (int i = 0; i < 10; i++) {
people[i] = new Person("Person" + (i+1));
}
for (Person person : people) {
Thread thread = new Thread(() -> person.passThrough(cave), person.getName());
thread.start();
}
cave.run();
}
}
```
在这个例子中,`main`函数启动10个线程,每个线程代表一个人,他们都尝试立即通过山洞。`Cave`类负责协调他们的顺序。当山洞满时,新来的会等待直到有人离开。运行这个程序将会看到10个人按照某种随机顺序依次通过山洞,打印出他们的名字。
用编写多线程应用程序,模拟多个人通过一个山洞,这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒。随机生成10个人,同时准备过此山洞,*显示一下每次通过山洞人的姓名。
为了模拟这种场景,你可以使用Java语言编写一个多线程程序。我们可以创建一个`Person`类作为人员的基本模型,包含姓名和过山洞的函数。然后创建一个名为`Tunnel`的类代表山洞,它维护一个队列来存储等待的人,并控制谁可以进入。
```java
import java.util.concurrent.*;
import java.util.Random;
class Person {
private String name;
private volatile boolean isInTunnel = false; // 标记是否在山洞中
public Person(String name) {
this.name = name;
}
public void startClimbing() {
new Thread(() -> {
try {
while (!isInTunnel) { // 等待进入山洞
Thread.sleep(100); // 模拟等待时间
}
System.out.println(Thread.currentThread().getName() + " started climbing (" + name + ")");
isInTunnel = true; // 进入山洞
try {
Thread.sleep(5000); // 模拟过山洞时间
} catch (InterruptedException e) {
e.printStackTrace();
}
isInTunnel = false; // 出山洞
System.out.println(Thread.currentThread().getName() + " finished climbing (" + name + ")");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
public class Tunnel {
private final Queue<Person> queue = new LinkedList<>();
private int current climberIndex = -1;
public synchronized void addPerson(Person person) {
queue.add(person);
if (currentClimberIndex == -1) {
currentClimberIndex = 0;
person.startClimbing();
}
}
public static void main(String[] args) {
Random random = new Random();
for (int i = 0; i < 10; i++) {
Person person = new Person("Person" + i);
new Thread(() -> {
System.out.println("Adding " + person.getName() + " to the queue");
new Tunnel().addPerson(person);
}).start();
}
}
}
```
在这个例子中,我们使用了`Thread.sleep()`模拟等待时间和过山洞的实际时间。注意,由于并发访问,`Person`类中的`isInTunnel`字段使用了`volatile`关键字保证可见性。每个新加入的人都会立即开始等待,一旦当前正在过山洞的人完成,就会唤醒并替换下一个人。
阅读全文