code: public void read(final long address, final byte[] data) throws Exception {
  
          if (blockCount == -1) {
              throw new IllegalStateException("You first have to open the Device!");
          }
  
          int blocks = data.length / blockSize;
  
          if (address < 0 || address + blocks > blockCount) {
              long adr = address < 0 ? address : address + blocks - 1;
              throw new IllegalArgumentException("Address " + adr + " out of range.");
          }
  
          if (data.length % blockSize != 0) {
              throw new IllegalArgumentException("Number of bytes is not a multiple of the blocksize!");
          }
  
          int parts = (blocks >= devices.length) ? devices.length : (int)blocks;
          barrier = new CyclicBarrier(parts + 1);
          int targetBlockCount;
          List<byte[]> targetData = new Vector<byte[]>();
          int targetBlockAddress = (int)address;
  
          for (int i = 0; i < parts; i++) {
              targetBlockCount = blocks / devices.length;
              if (i < (blocks % devices.length)) {
                  targetBlockCount++;
              }
              targetData.add(new byte[targetBlockCount * blockSize]);
  
              /** Start Thread to read Data from Target */
              if (targetBlockCount != 0) {
                  executor.execute(new ReadThread(devices[nextTarget], targetBlockAddress, targetData.get(i)));
              }
              targetBlockAddress += targetBlockCount;
              nextTarget = (nextTarget < devices.length - 1) ? nextTarget + 1 : 0;
          }
          barrier.await();
  
          /** Merge the results. */
          int pos = 0;
          for (int i = 0; i < targetData.size(); i++) {
              System.arraycopy(targetData.get(i), 0, data, pos, targetData.get(i).length);
              pos += targetData.get(i).length;
          }
      }
docs: {@inheritDoc}