Android BLE multiple connections

I am wondering how this can be achieved

To achieve multiple BLE connection you have to store multiple BluetoothGatt object and use those object for different device. To store multiple connection object of BluetoothGatt you can use Map<>

private Map<String, BluetoothGatt> connectedDeviceMap; 

On Service onCreate initialize the Map

connectedDeviceMap = new HashMap<String, BluetoothGatt>();

Then before calling device.connectGatt(this, false, mGattCallbacks); to connect to GATT Server check that device is already connected.

  BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress);
  int connectionState = mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);

  if(connectionState == BluetoothProfile.STATE_DISCONNECTED ){
   // connect your device
   device.connectGatt(this, false, mGattCallbacks);
  }else if( connectionState == BluetoothProfile.STATE_CONNECTED ){
   // already connected . send Broadcast if needed
  }

On BluetoothGattCallback if connection state is CONNECTED then store BluetoothGatt object on Map and if connection state is DISCONNECTED then remove it form Map

        @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status,
            int newState) {

        BluetoothDevice device = gatt.getDevice();
        String address = device.getAddress();

        if (newState == BluetoothProfile.STATE_CONNECTED) {

            Log.i(TAG, "Connected to GATT server.");

            if (!connectedDeviceMap.containsKey(address)) {
                  connectedDeviceMap.put(address, gatt);
              }
             // Broadcast if needed
            Log.i(TAG, "Attempting to start service discovery:" +
                    gatt.discoverServices());

        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.i(TAG, "Disconnected from GATT server.");
            if (connectedDeviceMap.containsKey(address)){
              BluetoothGatt bluetoothGatt = connectedDeviceMap.get(address);
              if( bluetoothGatt != null ){
                   bluetoothGatt.close();
                   bluetoothGatt = null;
              } 
              connectedDeviceMap.remove(address);                
            }
            // Broadcast if needed
        }
    }

Similarly onServicesDiscovered(BluetoothGatt gatt, int status) method you have BluetoothGatt connection object on parameter and you can get device from that BluetoothGatt. And other callback method like public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) you will get the device form gatt .

When you need to writeCharacteristic or writeDescriptor, get BluetoothGatt object from Map and use that BluetoothGatt object to call gatt.writeCharacteristic(characteristic) gatt.writeDescriptor(descriptor) for different connection.

Do I need a separate thread for each connection?

I think you don't need to use separate Thread for each connection. Just run the Service on a Background Thread.

Hope this help you.