I thread a cui ti riferisci in questo contesto sarebbero i famosi Lettori e Scrittori (un bel problemino conosciuto!). Se vuoi un esempio di programma che faccia uso di un thread lettore e di uno scrittore non c'è problema, te lo posto in calce al messaggio, però, come dice cristiano_longo, in questo caso particolare non ti sono di grande aiuto. In genere, questo tipo di thread si comportano in questo modo: lo scrittore scrive in un buffer e se questo è pieno, si blocca e attende; il lettore legge dal buffer e se questo è vuoto, si blocca e attente. Per quello che devi fare tu non credo sia di aiuto (né necessario) che il thread lettore si blocchi se il thread scrittore non ha ancora scritto i dati nel buffer (ossia non li ha ancora letti dal DB). In questo caso dovresti decidere come comportarti: vuoi far sì che quando avviene una richiesta di lettura un thread si occupi della lettura e fornisca i dati, oppure a te serve che un thread legga in continuo i dati dal db, li metta in un buffer e attenda che il lettore li consumi?

Questo è un esempio di problema dei Lettori / Scrittori:
codice:
public class Buffer {
   private int [] buffer;
   private int first;
   private int last;

   public Buffer() {
      buffer = new int[10];  // limito il buffer a 10 elementi
      first = last = 0;
   }

   public synchronized void aggiungiElemento(int elemento) {
      if (last == 9) {   // il buffer è pieno...
         try {
            wait();  // ...attendo che il lettore consumi almeno un elemento
         } catch (Exception e) {}
      }
      last++;
      buffer[last] = elemento;  // aggiungo l'elemento al buffer
      notify();
   }

   public synchronized int leggiElemento() {
      int tmp;
      if (last == 0) {
         try {
            wait();
         } catch (Exception e) {}
      }
      tmp = buffer[0];
      shiftaElementi();
      last--;
      notify();
      return tmp;
   }

   private void shiftaElementi() {
      for (int i=0; i<9; i++) buffer[i] = buffer[i+1];
      buffer[9] = 0;  //non necessario...
   }
}

public class Lettore extends Thread {
   private Buffer b;
   private int valore;
   private int somma;

   public Lettore(Buffer b) {
      this.b = b;
      valore = somma = 0;
   }

   public void run() {
      while (true) {
         valore = b.leggiElemento();
         somma += valore;
         System.out.println("Ultimo valore letto: " + valore);
         System.out.println("Somma attuale: " + somma);
      }
   }
}

public class Scrittore extends Thread {
   private Buffer b;
   private int valore;

   public Scrittore(Buffer b) {
      this.b = b;
      valore = 0;
   }

   public void run() {
      while (true) {
         valore = ((int)((Math.random() * 500000) % 64; // genero un numero a caso fra 0 e 63
         b.aggiungiElemento(valore);
      }
   }
}

class Programma {
   public static void main(String [] args) {
      Buffer b = new Buffer();
      Lettore l = new Lettore(b);
      Scrittore s = new Scrittore(b);
      s.start();
      l.start();
   }
}
Ciao.