Il tuo codice è parecchio sbagliato/inappropriato per alcune questioni.
Innanzitutto il problema tecnico che hai appena indicato è dovuto al fatto che i wait/notify vanno invocati su un oggetto di cui si possiede il lock (ovvero il thread corrente ha acquisito il lock). Pertanto wait() va usato in un contesto synchronized (metodo/blocco).
Inoltre wait generalmente va messo in un loop che testa una condizione, che è quella che deve "tenere" affinché il thread resti in attesa. Pensa, come esempio, ad una coda "bloccante" di dimensione massima fissa: finché la coda è piena, un put() deve far stare il thread in attesa. È proprio quel "finché la coda è piena" che deve essere tradotto in un loop che testa la condizione "coda piena". Questo perché ci potrebbero essere altri motivi per cui un thread si risveglia ma quello che conta è appunto la condizione.