src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java
changeset 48843 21efc1774302
parent 48586 8877e857fdd7
child 49433 b6671a111395
equal deleted inserted replaced
48842:a5a2e4770524 48843:21efc1774302
  1582 
  1582 
  1583     /** debugging */
  1583     /** debugging */
  1584     void checkInvariants() {
  1584     void checkInvariants() {
  1585         // meta-assertions
  1585         // meta-assertions
  1586         // assert lock.isHeldByCurrentThread();
  1586         // assert lock.isHeldByCurrentThread();
  1587         try {
  1587         if (!invariantsSatisfied()) {
  1588             // Unlike ArrayDeque, we have a count field but no spare slot.
  1588             String detail = String.format(
  1589             // We prefer ArrayDeque's strategy (and the names of its fields!),
  1589                 "takeIndex=%d putIndex=%d count=%d capacity=%d items=%s",
  1590             // but our field layout is baked into the serial form, and so is
  1590                 takeIndex, putIndex, count, items.length,
  1591             // too annoying to change.
  1591                 Arrays.toString(items));
  1592             //
  1592             System.err.println(detail);
  1593             // putIndex == takeIndex must be disambiguated by checking count.
  1593             throw new AssertionError(detail);
  1594             int capacity = items.length;
  1594         }
  1595             // assert capacity > 0;
  1595     }
  1596             // assert takeIndex >= 0 && takeIndex < capacity;
  1596 
  1597             // assert putIndex >= 0 && putIndex < capacity;
  1597     private boolean invariantsSatisfied() {
  1598             // assert count <= capacity;
  1598         // Unlike ArrayDeque, we have a count field but no spare slot.
  1599             // assert takeIndex == putIndex || items[takeIndex] != null;
  1599         // We prefer ArrayDeque's strategy (and the names of its fields!),
  1600             // assert count == capacity || items[putIndex] == null;
  1600         // but our field layout is baked into the serial form, and so is
  1601             // assert takeIndex == putIndex || items[dec(putIndex, capacity)] != null;
  1601         // too annoying to change.
  1602         } catch (Throwable t) {
  1602         //
  1603             System.err.printf("takeIndex=%d putIndex=%d count=%d capacity=%d%n",
  1603         // putIndex == takeIndex must be disambiguated by checking count.
  1604                               takeIndex, putIndex, count, items.length);
  1604         int capacity = items.length;
  1605             System.err.printf("items=%s%n",
  1605         return capacity > 0
  1606                               Arrays.toString(items));
  1606             && items.getClass() == Object[].class
  1607             throw t;
  1607             && (takeIndex | putIndex | count) >= 0
  1608         }
  1608             && takeIndex <  capacity
  1609     }
  1609             && putIndex  <  capacity
  1610 
  1610             && count     <= capacity
  1611     /**
  1611             && (putIndex - takeIndex - count) % capacity == 0
  1612      * Deserializes this queue and then checks some invariants.
  1612             && (count == 0 || items[takeIndex] != null)
  1613      *
  1613             && (count == capacity || items[putIndex] == null)
  1614      * @param s the input stream
  1614             && (count == 0 || items[dec(putIndex, capacity)] != null);
       
  1615     }
       
  1616 
       
  1617     /**
       
  1618      * Reconstitutes this queue from a stream (that is, deserializes it).
       
  1619      *
       
  1620      * @param s the stream
  1615      * @throws ClassNotFoundException if the class of a serialized object
  1621      * @throws ClassNotFoundException if the class of a serialized object
  1616      *         could not be found
  1622      *         could not be found
  1617      * @throws java.io.InvalidObjectException if invariants are violated
  1623      * @throws java.io.InvalidObjectException if invariants are violated
  1618      * @throws java.io.IOException if an I/O error occurs
  1624      * @throws java.io.IOException if an I/O error occurs
  1619      */
  1625      */
  1621         throws java.io.IOException, ClassNotFoundException {
  1627         throws java.io.IOException, ClassNotFoundException {
  1622 
  1628 
  1623         // Read in items array and various fields
  1629         // Read in items array and various fields
  1624         s.defaultReadObject();
  1630         s.defaultReadObject();
  1625 
  1631 
  1626         // Check invariants over count and index fields. Note that
  1632         if (!invariantsSatisfied())
  1627         // if putIndex==takeIndex, count can be either 0 or items.length.
       
  1628         if (items.length == 0 ||
       
  1629             takeIndex < 0 || takeIndex >= items.length ||
       
  1630             putIndex  < 0 || putIndex  >= items.length ||
       
  1631             count < 0     || count     >  items.length ||
       
  1632             Math.floorMod(putIndex - takeIndex, items.length) !=
       
  1633             Math.floorMod(count, items.length)) {
       
  1634             throw new java.io.InvalidObjectException("invariants violated");
  1633             throw new java.io.InvalidObjectException("invariants violated");
  1635         }
       
  1636     }
  1634     }
  1637 }
  1635 }