为了账号安全,请及时绑定邮箱和手机立即绑定

Java多线程程序

Java多线程程序

温温酱 2022-07-06 17:29:54
我的任务是创建一个程序,它具有:班级Client班级Gate班级Museum通过使用类Client进入和离开。博物馆一次最多可接待 5 位顾客。MuseumGate当我Clients在某个时候输入 1000 时,输出会给我不需要的数字。样本输出:Client (358) is leaving the Museum!   number of customers: 2Client (214) is entering the Museum!   number of customers: 3Client (214) is leaving the Museum!   number of customers: 2Client (73) is entering the Museum!   number of customers: 5Client (73) is leaving the Museum!   number of customers: 5Client (397) is entering the Museum!   number of customers: 5Client (76) is entering the Museum!   number of customers: 6----------------------------------------------------------------Client (930) is entering the Museum!   number of customers: 7Client (930) is leaving the Museum!   number of customers: 6Client (308) is entering the Museum!   number of customers: 6Client (183) is entering the Museum!   number of customers: 6Client (183) is leaving the Museum!   number of customers: 5----------------------------------------------------------------Client (647) is entering the Museum!   number of customers: 7Client (647) is leaving the Museum!   number of customers: 6----------------------------------------------------------------Client (540) is entering the Museum!   number of customers: 7我期望客户会在某个随机时间尝试进入,当博物馆中有 5 个或更多客户时,他们将不得不等待其他线程结束它的任务。这是我的代码:Client.javapackage client;import gate.Gate;import museum.Museum;import java.util.Random;public class Client extends Thread {    private static int id = 0;    private int clientID;    public Client() {        Client.id++;        this.clientID = id;    }    @Override    public void run() {        this.enterMuseum();        this.leaveMuseum();    }    ///////////////////////////////////////////////////////////////////////////////////    private void enterMuseum() {        try {            Thread.sleep(new Random().nextInt(401) + 100);        } catch (InterruptedException e) {            e.printStackTrace();        }
查看完整描述

1 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

一些建议,不要使用公共静态变量和静态方法,如博物馆.getGate() 或原子客户计数器(这使得更难理解谁在使用什么)。此外,客户端类应该与“计数器”逻辑完全隔离;也就是说,客户端应该简单地调用 gate.enter(),并且访问检查应该在 Gate 或 Museum 中完成。


然后是“关键”部分,您尝试在其中为客户分配“许可”,在


 while (true) {

   if (Gate.atomCustomer.get() < 5) {

     //use museum.tryEnter() instead..

     Museum.getGate(0).enter(this);

     break;

   }

 }

在这里,如果两个线程同时调用get() ,它们都会发现客户的数量是eg。4,他们都会进入(并发问题)。


确保只有一个客户端获得许可的一种方法是将嵌套调用添加到某些同步方法,例如


private synchronized boolean tryEnter() {

    if (counter<5) {

        counter++;

        return true;

    }

    else {

        return false;

    }

}

但是分配许可的更好方法是使用信号量(这样你甚至不需要那个繁忙的循环)。https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html


查看完整回答
反对 回复 2022-07-06
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号