Is my sketch 'thread safe'?
There is indeed a race condition in your code: if an interrupt fires
while you are reading one of the counters, you might read garbage. If it
fires between reading and resetting the counter, you loose one count.

The way to prevent the race is to block interrupts while the main thread
(everything that does not run in interrupt context) accesses the
counters. BTW, do not forget to make the counters volatile.

The portions of the code that run with interrupts disabled are called
“critical sections”, and you should keep them as short as possible in
order to limit the interrupt latency they introduce. Typically, within
those critical sections you do nothing more than access the shared
variables. Example:

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis &gt; interval) {
    previousMillis = currentMillis;
    noInterrupts();  // start of critical section
    int counter1Copy = counter1;
    counter1 = 0;
    interrupts();  // end of critical section
    Serial.print("A");
    Serial.println(counter1Copy);
    noInterrupts();  // start of critical section
    int counter2Copy = counter2;
    counter2 = 0;
    interrupts();  // end of critical section
    Serial.print("D");
    Serial.println(counter2Copy);
  }
}