publicclassTestextendsThread{staticStringsName="good";publicstaticvoidmain(Stringargv[]){Testt=newTest();t.nameTest(sName);System.out.println(sName);}publicvoidnameTest(StringsName){sName=sName+" idea ";start();}publicvoidrun(){for(inti=0;i<4;i++){sName=sName+" "+i;}}}
Ele imprime apenas "good"; No caso de "idea" aparentemente ele concatena apenas localmente no próprio método.
Mas quanto ao RUN ? o sName vem de onde e por que não é modificado no static?
Primeiro de tudo, esse comportamento não é garantido. Como vc está lidando com threads e não há sincronização, não há garantias de nada.
Você pode, no meio do programa, ter a String alterada. Quem define a ordem de quem executará e quando é o escalonador.
Agora vou te explicar pq é pouco provável que isso ocorra. Cada thread tem em si uma cópia do valor da variável, justamente para maximizar o paralelismo. Mesmo que a thread 1 altere o valor de sName, a thread 2 não enxergará imediatamente a mudança. Essa cópia não é usada em trechos sincronizados. Se quiser evitar a cópia, declare a variável sName como volatile.
andersonlandim
Não sabia destes detalhes, valeu pela explicação!
Mas na parte não enxergará imediatamente a mudança, isso quer dizer que em algum momento, mesmo que não seja garantido, a variável poderia ter sido modificada?
ViniGodoy
Sim. São cada thread tem sua cópia. Um bloco synchronized sincroniza das cópias com o valor original. E, arbitrariamente, a VM pode fazer esse sincronismo também, se achar necessário.
Por isso que acesso concorrente sempre, sempre mesmo, deve ser feito num bloco sincronizado (ou, se for muito simples, com volatiles).
andersonlandim
ViniGodoy:
Sim. São cada thread tem sua cópia. Um bloco synchronized sincroniza das cópias com o valor original. E, arbitrariamente, a VM pode fazer esse sincronismo também, se achar necessário.
Por isso que acesso concorrente sempre, sempre mesmo, deve ser feito num bloco sincronizado (ou, se for muito simples, com volatiles).
Entendi cara, só tenho a agradecer pela aula! hehe…