【问题标题】:Java threads not working correctly with linkedlistJava 线程无法与链表一起正常工作
【发布时间】:2010-04-04 15:05:10
【问题描述】:

您好,我正在研究睡眠理发师的问题。除了在他们到达时有优先客户之外,他们排在队伍的最前面,他们是下一个理发的人。

我正在使用linkedlist,如果我看到优先客户,我将他放在列表的开头,如果客户不是优先客户,他将转到列表的末尾。然后我调用 wantHaircut 方法获取列表的第一个元素。

我的问题是客户正在按照他们到达的顺序进行处理,优先客户必须等待。这是发生这一切的代码。任何想法我做错了什么?谢谢

 public void arrivedBarbershop(Customer c){

      if(waiting < numChairs && c.isPriority()){
          System.out.println("Customer " + c.getID() + ": is a priority customer - SITTING -");
          mutex.up();             
          customer_list.addFirst(c);
      }
      else if(waiting >= numChairs && c.isPriority()){
          System.out.println("Customer " + c.getID() + ": is a priority customer - STANDING -");
          mutex.up();
          customer_list.addFirst(c);
      } 
      else if(waiting < numChairs && !c.isPriority()){
           waiting++;
           System.out.println("Customer " + c.getID()  + ": arrived, sitting in the waiting room");
          customer_list.addLast(c);
           customers.up(); // increment waiting customers

       }
       else if(waiting >= numChairs && !c.isPriority()) {

         System.out.println("Customer " + c.getID() + ": went to another barber because waiting room was full - " + waiting + " waiting");
         mutex.up();
       }

      if(!customer_list.isEmpty()){
         this.wantHairCut(customer_list.removeFirst());
      }

   }

   public void wantHairCut(Customer c) {
          mutex.up();
          barber.down();  // waits for being allowed in barber chair
          System.out.println("Customer " + c.getID() + ": getting haircut");
          try {
             /** haircut takes between 1 and 2 seconds **/
              Thread.sleep(Barbershop.randomInt(1, 2) * 1000);
          } catch (InterruptedException e) { }
          System.out.println("Barber: finished cutting customer " + c.getID() + "'s hair");
          c.gotHaircut = true;          
          cutting.up();   // signals cutting has finished

          /** customer must pay now **/
          this.wantToCashout(c);          
   }

【问题讨论】:

  • 这是候诊室的椅子数量。如果他们都被带走,客户离开,除非他是优先客户,否则他可以站着等待。
  • 我使用了向量而不是链表,因为向量是线程安全的,但我仍然遇到同样的问题。我不知道我做错了什么。

标签: java multithreading synchronization linked-list


【解决方案1】:

您必须使用同步集合:

Collections.synchronizedList(List<Object> list)

此方法根据参数列表返回同步的List实例

【讨论】:

  • 我不知道我是否做错了,但这也不起作用... list = Collections.synchronizedList(customer_list);
  • 你知道逻辑错误是什么吗?我似乎无法弄清楚。
  • 很遗憾,我没有看到错误
【解决方案2】:

我很确定逻辑错误就在这里:

  if(waiting < numChairs && c.isPriority()){
      System.out.println("Customer " + c.getID() + ": is a priority customer - SITTING -");
      mutex.up();             
      customer_list.addFirst(c);
  }
  else if(waiting >= numChairs && c.isPriority()){
      System.out.println("Customer " + c.getID() + ": is a priority customer - STANDING -");
      mutex.up();
      customer_list.addFirst(c);
  } 

是的,避免复制/粘贴编程!

【讨论】:

  • @user69514:if/else 构造的两个部分中的代码块完全相同。
  • 他们应该做同样的事情。一个将打印 STANDING,另一个将打印 SITTING。一种是顾客多于椅子,另一种是顾客少于椅子。我不明白这是如何导致程序无法正常工作的......
【解决方案3】:

每当您修改列表时,您可能应该将该代码放在同步块中。

一种方法:

synchronized(customer_list) {
 customer_list.addFirst(c);
}

另一个,这样您就不必到处编写代码了:

public synchronized void addCustomerAtStart(Customer c) {
 customer_list.addFirst(c);
}

然后替换那个函数。

当您执行 customer.up() 时也是如此,看起来它也需要同步,否则您可能会遇到很多不一致的行为。

您甚至不需要使用“mutex.up()” 提示:如果您必须同步线程,您可能想看看 CountDownLatch,非常易于使用,非常适合线程同步。

【讨论】:

    【解决方案4】:

    您的代码将客户添加到列表(开始或结束),然后从列表中删除客户。该列表最多只包含一位客户,因此客户按添加顺序进行处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      相关资源
      最近更新 更多