Originariamente inviato da sirluca
Ho fatto il tuo stesso ragionamento e lo stavo per scrivere! Grazie ancora per la risposta!


Originariamente inviato da sirluca
p.s. ragionando mi è anche venuto in mente che join deve per forza far rilasciare i lock acquisiti dal thread in cui è chiamato
No, join non rilascia lock.

Originariamente inviato da sirluca
il join sennò supponendo che il main ha il lock sull' oggetto "a" e il thread pincopallo su cui è eseguito il join ha bisogno del lock su "a" si avrebbe un' attessa circolare causata dal fatto che il thread chiede il lock su "a" che è tenuto dal main che non lo rilascerà mai perchè aspetta che il thread pincopallo finisca..
Se nel tuo main invece del

Thread.sleep(500);

metti:

codice:
synchronized(a) {
    t.join();
    t2.join();
}
Succede che il main-thread "tiene" il lock su 'a'. Ma il main-thread attende che t/t2 finiscano mentre ... i thread t/t2 attendono di acquisire il lock su 'a'.
Risultato: dead-lock!

Nota: in realtà racchiudendo con synchronized solo i join, è possibile che t/t2 riescano a terminare prima che il main-thread entri in questo blocco synchronized, è una ipotesi rara ma possibile.
Se racchiudi con synchronized(a) { } sia start che join, il dead-lock è sicuro al 100%.

Se succedono queste cose non è che join, secondo te, dovrebbe rilasciare i lock .... la colpa è del programmatore ...