tentando fazer controle de acesso concorrente a um mesmo recurso utilizando
'synchronized' me deparei com uma situacao meia estranha. para poder explicar
melhor o resultado um source code mostrando a situacao vai abaixo...
import java.util.Random;
class nThread extends Thread {
private TestSync o = null;
public nThread (TestSync o) {
this.o = o;
};
public void run() {
Random y = new Random();
int x = y.nextInt(50) + y.nextInt(50);
while (true) {
o.putValueOnA(this);
try {
sleep(x);
}
catch (InterruptedException e) {
};
o.getValueOfA(this);
};
};
};
public class TestSync {
String a = new String();
String b = new String();
Object c = new Object();
public void putValueOnA(Thread x) {
synchronized (this) {
a = Long.toString(System.currentTimeMillis());
System.out.print("put(" + x.getName() + "): ");
System.out.print("put on 'a': " + a + ". ");
System.out.println("***");
};
};
public void getValueOfA(Thread x) {
synchronized (this) {
System.out.print("get(" + x.getName() + "): ");
System.out.print("get from 'a': " + a + ". ");
System.out.println("+++");
};
};
public static void main (String[] args) {
TestSync x = new TestSync();
for (int i = 0; i < 10; i++) {
new nThread(x).start();
};
};
};
o interessante (e que motivou este correio) eh o seguinte:
1) como estah, este programa, aparentemente, funciona corretamente. um
resultado da operacao eh o seguinte:
put(Thread-1): put on 'a': 927309068577. ***
put(Thread-2): put on 'a': 927309068757. ***
put(Thread-3): put on 'a': 927309068767. ***
put(Thread-4): put on 'a': 927309068777. ***
put(Thread-5): put on 'a': 927309068777. ***
put(Thread-6): put on 'a': 927309068797. ***
put(Thread-7): put on 'a': 927309068807. ***
put(Thread-8): put on 'a': 927309068817. ***
put(Thread-9): put on 'a': 927309068817. ***
put(Thread-0): put on 'a': 927309068857. ***
get(Thread-4): get from 'a': 927309068857. +++
get(Thread-5): get from 'a': 927309068857. +++
get(Thread-6): get from 'a': 927309068857. +++
get(Thread-7): get from 'a': 927309068857. +++
get(Thread-8): get from 'a': 927309068857. +++
get(Thread-2): get from 'a': 927309068857. +++
get(Thread-3): get from 'a': 927309068857. +++
put(Thread-4): put on 'a': 927309068897. ***
put(Thread-5): put on 'a': 927309068897. ***
get(Thread-9): get from 'a': 927309068897. +++
put(Thread-6): put on 'a': 927309068907. ***
get(Thread-0): get from 'a': 927309068907. +++
put(Thread-7): put on 'a': 927309068917. ***
put(Thread-8): put on 'a': 927309068917. ***
put(Thread-2): put on 'a': 927309068917. ***
put(Thread-3): put on 'a': 927309068927. ***
put(Thread-9): put on 'a': 927309068927. ***
put(Thread-0): put on 'a': 927309068927. ***
get(Thread-4): get from 'a': 927309068927. +++
get(Thread-5): get from 'a': 927309068927. +++
get(Thread-6): get from 'a': 927309068927. +++
put(Thread-4): put on 'a': 927309068947. ***
get(Thread-7): get from 'a': 927309068947. +++
put(Thread-6): put on 'a': 927309068967. ***
get(Thread-8): get from 'a': 927309068967. +++
put(Thread-5): put on 'a': 927309068977. ***
get(Thread-9): get from 'a': 927309068977. +++
get(Thread-0): get from 'a': 927309068977. +++
put(Thread-8): put on 'a': 927309068977. ***
put(Thread-9): put on 'a': 927309068987. ***
put(Thread-0): put on 'a': 927309068987. ***
put(Thread-7): put on 'a': 927309068987. ***
get(Thread-4): get from 'a': 927309068987. +++
get(Thread-6): get from 'a': 927309068987. +++
put(Thread-6): put on 'a': 927309068997. ***
get(Thread-2): get from 'a': 927309068997. +++
put(Thread-2): put on 'a': 927309069007. ***
get(Thread-5): get from 'a': 927309069007. +++
put(Thread-5): put on 'a': 927309069007. ***
get(Thread-3): get from 'a': 927309069007. +++
put(Thread-3): put on 'a': 927309069017. ***
get(Thread-8): get from 'a': 927309069017. +++
put(Thread-8): put on 'a': 927309069027. ***
get(Thread-0): get from 'a': 927309069027. +++
put(Thread-0): put on 'a': 927309069027. ***
get(Thread-7): get from 'a': 927309069027. +++
put(Thread-7): put on 'a': 927309069038. ***
get(Thread-5): get from 'a': 927309069038. +++
put(Thread-5): put on 'a': 927309069058. ***
get(Thread-8): get from 'a': 927309069058. +++
put(Thread-8): put on 'a': 927309069058. ***
put(Thread-4): put on 'a': 927309069068. ***
get(Thread-9): get from 'a': 927309069068. +++
put(Thread-9): put on 'a': 927309069068. ***
2) agora, se substituirmos as linhas
synchronized (this) {
por
synchronized (c) {
onde c eh o 'Object c', aparentemente, tambem funciona (isto eh o mesmo
que se faz em c++: cria-se um objeto mutex que gerencia o monitor de lock). o
resultado eh semelhante ao anterior.
3) agora se substituirmos o
synchronized (this) {
por
synchronized (a) {
para que o proprio objeto cujo acesso eh feito concorrentemente seja o
gerenciador dos locks de acesso o resultado mudou completamente, parecendo que a
JVM nao respeitou o lock. um exemplo do resultado estah abaixo.
put(Thread-0): put(Thread-1): put(Thread-2): put(Thread-3): put(Thread-4):
put(Thread-5): put(Thread-6): put(Thread-7):
put(Thread-8): put(Thread-9): put on 'a': 927309512355. put on 'a':
927309512355. put on 'a': 927309512355. put o
n 'a': 927309512355. put on 'a': 927309512355. put on 'a': 927309512355.
put on 'a': 927309512355. put on 'a':
927309512355. put on 'a': 927309512355. ***
***
***
***
***
***
***
***
***
get(Thread-1): get from 'a': 927309512355. +++
get(Thread-2): get from 'a': 927309512355. +++
put(Thread-1): put on 'a': 927309512655. ***
get(Thread-5): get from 'a': 927309512655. +++
put(Thread-5): put on 'a': 927309512655. ***
get(Thread-6): get from 'a': 927309512655. +++
put(Thread-6): put on 'a': 927309512665. ***
get(Thread-3): get from 'a': 927309512665. +++
put(Thread-3): put on 'a': 927309512675. ***
get(Thread-4): get from 'a': 927309512675. +++
put(Thread-4): put on 'a': 927309512685. ***
get(Thread-1): get from 'a': 927309512685. +++
put(Thread-1): put on 'a': 927309512685. ***
put(Thread-2): get(Thread-8): get from 'a': 927309512685. +++
put(Thread-8): put on 'a': 927309512695. ***
get(Thread-9): get from 'a': 927309512695. +++
put(Thread-9): put on 'a': 927309512705. ***
put on 'a': 927309512705. ***
get(Thread-7): get from 'a': 927309512705. +++
put(Thread-7): put on 'a': 927309512715. ***
put on 'a': 927309512715. ***
get(Thread-1): get from 'a': 927309512715. +++
put(Thread-1): put on 'a': 927309512715. ***
get(Thread-5): get from 'a': 927309512715. +++
get(Thread-6): get from 'a': 927309512715. +++
get(Thread-3): get from 'a': 927309512715. +++
get(Thread-2): get from 'a': 927309512715. +++
get(Thread-4): get from 'a': 927309512715. +++
put(Thread-6): put on 'a': 927309512756. ***
get(Thread-8): get from 'a': 927309512756. +++
put(Thread-8): put on 'a': 927309512766. ***
get(Thread-1): get from 'a': 927309512766. +++
put(Thread-1): put on 'a': 927309512776. ***
get(Thread-9): get from 'a': 927309512776. +++
put(Thread-9): put on 'a': 927309512776. ***
put(Thread-3): put on 'a': 927309512786. ***
put(Thread-2): put on 'a': 927309512786. ***
put(Thread-4): put on 'a': 927309512786. ***
put(Thread-5): put on 'a': 927309512786. ***
get(Thread-7): get from 'a': 927309512786. +++
put(Thread-7): put on 'a': 927309512796. ***
get(Thread-0): get from 'a': 927309512796. +++
get(Thread-1): get from 'a': 927309512796. +++
put(Thread-1): put on 'a': 927309512806. ***
put(Thread-0): put on 'a': 927309512806. ***
get(Thread-2): get from 'a': 927309512806. +++
put(Thread-2): put on 'a': 927309512826. ***
get(Thread-6): get from 'a': 927309512826. +++
put(Thread-6): put on 'a': 927309512836. ***
get(Thread-8): get from 'a': 927309512836. +++
put(Thread-8): put on 'a': 927309512846. ***
get(Thread-9): get from 'a': 927309512846. +++
put(Thread-9): put on 'a': 927309512856. ***
get(Thread-3): get from 'a': 927309512856. +++
put(Thread-3): put on 'a': 927309512856. ***
get(Thread-4): get from 'a': 927309512856. +++
put(Thread-4): put on 'a': 927309512896. ***
get(Thread-2): get from 'a': 927309512896. +++
get(Thread-1): get from 'a': 927309512896. +++
get(Thread-5): get from 'a': 927309512896. +++
get(Thread-7): get from 'a': 927309512896. +++
get(Thread-6): get from 'a': 927309512896. +++
get(Thread-0): get from 'a': 927309512896. +++
get(Thread-8): get from 'a': 927309512896. +++
get(Thread-9): get from 'a': 927309512896. +++
get(Thread-3): get from 'a': 927309512896. +++
put(Thread-1): put on 'a': 927309513296. ***
put(Thread-5): put on 'a': 927309513326. ***
get(Thread-1): get from 'a': 927309513326. +++
put(Thread-1): put on 'a': 927309513406. ***
put(Thread-7): put on 'a': 927309513447. ***
get(Thread-5): get from 'a': 927309513447. +++
put(Thread-5): put on 'a': 927309513527. ***
get(Thread-1): get from 'a': 927309513527. +++
put(Thread-1): put on 'a': 927309513607. ***
put(Thread-6): put on 'a': 927309513637. ***
get(Thread-7): get from 'a': 927309513637. +++
put(Thread-7): put on 'a': 927309513717. ***
get(Thread-5): get from 'a': 927309513717. +++
put(Thread-5): put on 'a': 927309513797. ***
get(Thread-1): get from 'a': 927309513797. +++
put(Thread-1): put on 'a': 927309513877. ***
put(Thread-0): put on 'a': 927309513917. ***
get(Thread-6): get from 'a': 927309513917. +++^C
algum de VCs poderia me ajudar a dizer porque isto ocorreu? seria um erro meu
de interpretacao de como o 'synchronized' funciona (antes eu trabalhava com
c++...)? seria um erro de programacao meu? ou seria um bug da JVM - estou
usando JDK 1.2.1, compilei o programa com javac e javac-ea e o resultado foi o
mesmo...
muito obrigado a todos...
Tedesco...
* Para nao receber mais e-mails da lista, acesse
<http://www.sun.com.br:8080/guest/RemoteAvailableLists>, coloque seu e-mail, escolha a
lista <[EMAIL PROTECTED]> e de um <submit>.