Java 承载力等于N的滑雪升降机。
我正在学习多线程。这是我的第一项任务。我写了这段代码,我不能继续了。任务: 容量等于N的滑雪升降机。 客户机有一个权重(随机Ki值),它们是在中执行的线程 循环:Java 承载力等于N的滑雪升降机。,java,multithreading,Java,Multithreading,我正在学习多线程。这是我的第一项任务。我写了这段代码,我不能继续了。任务: 容量等于N的滑雪升降机。 客户机有一个权重(随机Ki值),它们是在中执行的线程 循环: 下坡(睡眠(大随机值) 试着进入电梯(如果客户的总重量 小于或等于N) 如果失败-他们正在等待(睡眠(小随机值) 并重新执行上一点 如果成功的话,它们就会上升 } 我有三个问题无法解决: 第一个要进入的人必须是第一个试图进入的人。(就像在队列中一样) 第一个上电梯的客户也必须是第一个下电梯的客户 我的程序中的监视器是什么 提前感谢
提前感谢:)显然,系统中的瓶颈是lift。lift只能有N个并发用户 另外,3.提到了监视器。在阅读了监视器是什么之后,你应该明白它允许独占访问有限的资源,电梯
因此,请设计电梯通道,尝试获取N个监视器中的一个,等待片刻,最后不要忘记释放监视器,以便其他人可以获取它。我认为这个问题属于 您的客户应该有一个状态,如“topofthemountaninreached”、“liftstationreacted”、“liftEntered” 然后,您的客户机等待此事件发生。这也是您要监视哪个元素的问题的答案-状态或客户机本身 对于队列,可以使用
ArrayListBlockingQueue
。
然后,您的SkiLift必须等待新客户到达并将其放入电梯。客户进入电梯后,电梯还会通知客户其已进入电梯。到达电梯顶部时,电梯还会通知客户
下面是这样一个解决方案的示例。
它使用Java Executor服务来安排事件,以使客户机离开电梯,并到达下坡段末端的电梯站。这也可以以不同的方式解决
客户:
package skilift;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SkiLift implements Runnable{
private ScheduledExecutorService getOutClientExecutor;
public SkiLift() {
getOutClientExecutor = Executors.newScheduledThreadPool(50);
waitingClientsQueue = new ArrayBlockingQueue<>(1000);
occupiedSeats = new ArrayList<>();
}
private final ArrayList<Client> occupiedSeats;
private long usedCapacity;
private final ArrayBlockingQueue<Client> waitingClientsQueue;
private final long capacity = 500;
public void add(Client client) {
synchronized(waitingClientsQueue) {
waitingClientsQueue.add(client);
waitingClientsQueue.notify();
}
}
private synchronized void occupySeat(Client client) {
occupiedSeats.add(client);
usedCapacity += client.weight;
}
private synchronized void getClientOut(Client client) {
occupiedSeats.remove(client);
usedCapacity -= client.weight;
// notify the waitingClientQueue that the capacity has changed
synchronized (waitingClientsQueue) {
waitingClientsQueue.notify();
}
client.topReached();
}
public void run() {
while (true) {
synchronized(waitingClientsQueue) {
try {
if (!waitingClientsQueue.isEmpty()) {
Client c = waitingClientsQueue.peek();
if (usedCapacity + c.weight <= capacity) {
occupySeat(waitingClientsQueue.poll());
getOutClientExecutor.schedule(() -> {
getClientOut(c);
}, 2, TimeUnit.SECONDS);
} else {
waitingClientsQueue.wait();
}
} else {
waitingClientsQueue.wait();
}
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
}
}
电梯:
package-skilift;
导入java.util.ArrayList;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.concurrent.Executors;
导入java.util.concurrent.ScheduledExecutorService;
导入java.util.concurrent.TimeUnit;
公共类SkiLift实现可运行{
私有ScheduledExecutorService getOutClientExecutor;
公共升降机(){
getOutClientExecutor=Executors.newScheduledThreadPool(50);
waitingClientsQueue=新的ArrayBlockingQueue(1000);
OccuppiedSeats=新ArrayList();
}
私人最终ArrayList占用座位;
私人长期使用能力;
专用最终阵列锁定队列等待客户端队列;
私人最终长期容量=500;
公共作废添加(客户端){
已同步(waitingClientsQueue){
waitingclientsque.add(客户端);
waitingclientsque.notify();
}
}
专用同步无效占用席位(客户端){
占用座位。添加(客户);
usedCapacity+=客户端重量;
}
私有同步的void getClientOut(客户端){
占用座位。移除(客户);
使用容量-=客户重量;
//通知waitingClientQueue容量已更改
已同步(waitingClientsQueue){
waitingclientsque.notify();
}
client.topreach();
}
公开募捐{
while(true){
已同步(waitingClientsQueue){
试一试{
如果(!waitingclientsquee.isEmpty()){
客户端c=waitingclientsquee.peek();
如果(使用容量+c.重量){
getClientOut(c);
},2,时间单位(秒);
}否则{
waitingclientsque.wait();
}
}否则{
waitingclientsque.wait();
}
}捕获(中断异常ie){
Thread.currentThread().interrupt();
}
}
}
}
}
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Client implements Runnable{
final ScheduledExecutorService dhexceutors = Executors.newScheduledThreadPool(500);
final static Random DHRANDOM = new Random();
final long weight;
public enum State {
goDownhill,
waitForLift,
goUp,
onTop,
}
private State state;
public SkiLift lift;
public Client(long weight,SkiLift lift) {
this.lift = lift;
this.weight = weight;
this.state = State.onTop;
goDownHill();
}
private void enterLift() {
lift.add(this);
}
private void goDownHill() {
synchronized (this) {
state = State.goDownhill;
this.notify();
}
dhexceutors.schedule(() -> {
liftStationReached();
}, DHRANDOM.nextInt(500), TimeUnit.MILLISECONDS);
}
public void liftStationReached() {
synchronized(this) {
state = State.waitForLift;
this.notify();
}
}
public void topReached() {
synchronized(this) {
state = State.onTop;
this.notify();
}
}
public void liftEntered() {
synchronized(this) {
state = State.goUp;
this.notify();
}
}
public void run() {
synchronized(this) {
while (true) {
try {
this.wait();
switch (state) {
case waitForLift:
enterLift();
break;
case goUp:
// just wait for the topReached event
break;
case goDownhill:
// just wait for reaching the lift.
break;
case onTop:
goDownHill();
break;
}
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
}
}
package skilift;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SkiLift implements Runnable{
private ScheduledExecutorService getOutClientExecutor;
public SkiLift() {
getOutClientExecutor = Executors.newScheduledThreadPool(50);
waitingClientsQueue = new ArrayBlockingQueue<>(1000);
occupiedSeats = new ArrayList<>();
}
private final ArrayList<Client> occupiedSeats;
private long usedCapacity;
private final ArrayBlockingQueue<Client> waitingClientsQueue;
private final long capacity = 500;
public void add(Client client) {
synchronized(waitingClientsQueue) {
waitingClientsQueue.add(client);
waitingClientsQueue.notify();
}
}
private synchronized void occupySeat(Client client) {
occupiedSeats.add(client);
usedCapacity += client.weight;
}
private synchronized void getClientOut(Client client) {
occupiedSeats.remove(client);
usedCapacity -= client.weight;
// notify the waitingClientQueue that the capacity has changed
synchronized (waitingClientsQueue) {
waitingClientsQueue.notify();
}
client.topReached();
}
public void run() {
while (true) {
synchronized(waitingClientsQueue) {
try {
if (!waitingClientsQueue.isEmpty()) {
Client c = waitingClientsQueue.peek();
if (usedCapacity + c.weight <= capacity) {
occupySeat(waitingClientsQueue.poll());
getOutClientExecutor.schedule(() -> {
getClientOut(c);
}, 2, TimeUnit.SECONDS);
} else {
waitingClientsQueue.wait();
}
} else {
waitingClientsQueue.wait();
}
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
}
}