Ja li por ai que o objeto Vector é synchronized por natureza !
Mas estou tendo alguns problemas , acredito que relacionado a falha desse principio ! (se é que isso é possível)
Eu estou usando uma jList com o conteudo de um Vector
e no processamento dos dados uma thread move os elementos
da jList da esquerda pra jList da direita .
com esse método aqui :
public void listChange(int index)
{
data2.add(data.remove(index));
rebuildjList1();
rebuildjList2();
}
public void rebuildjList1()
{
jList1.setListData(data);
}
public void rebuildjList2()
{
jList2.setListData(data2);
}
ja até tentei colocar esse método como synchronized mas não resolveu !
Apesar de funcionalmente o programa não apresentar falhas hora ou otra
no console é disparado algumas exceções , variando apenas os numeros da indicação
com o index de onde ocorreu a ArrayIndexOutOfBoundsException !
Abaixo segue um exemplo , como eu disse a mensagem é sempre a mesma muda as vezes é os indices que
indicam o ponto da excecao no vetor.
[quote]
[color=darkred]Exception in thread “AWT-EventQueue-0” java.lang.ArrayIndexOutOfBoundsException: 5 >= 4[/color]
[color=blue] at java.util.Vector.elementAt(Vector.java:432)
at javax.swing.JList$5.getElementAt(JList.java:1250)
at javax.swing.plaf.basic.BasicListUI.paintCell(BasicListUI.java:185)
at javax.swing.plaf.basic.BasicListUI.paint(BasicListUI.java:290)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
at javax.swing.JComponent.paintComponent(JComponent.java:742)
at javax.swing.JComponent.paint(JComponent.java:1005)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4963)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4916)
at javax.swing.JComponent._paintImmediately(JComponent.java:4859)
at javax.swing.JComponent.paintImmediately(JComponent.java:4666)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:114)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)[/color][/quote]
Eu suponho que que esteja havendo algum conflito entre a thread que está varrendo as jList e Thread do awt que dispara os eventos , mas eu nao sei como eu posso dar um jeito nisso !
O vetor tem todos métodos sincronizados.
Isso só significa que seus métodos são atômicos, isso é, uma thread não poderá dar remove enquanto outra estiver fazendo add. Mas a segurança para por aí. A classe não protege contra coisas que acontecem “entre” a chamada de dois métodos. Por exemplo:
v.add("Vinicius");
v.add("João"); //Pode ter havido preempção antes do add("João");
No seu caso, como é a maioria das vezes, ainda é preferível usar o List no lugar do Vector e sincronizar os métodos da sua classe que está usando o List.
Aliás, dificilmente é uma boa escolha trocar List pelo Vector. Até porque, é possível gerar uma versão sincronizada da lista, só nos pontos onde a sincronização é necessária. Basta fazer:
List<SuaClasse> suaListaSincronizada = Collections.synchronizedList(suaLista);
Isso cria um wrapper na lista original, com a capacidade de sincronização.
Agora, se vc sincronizou todos os pontos de acesso, você deve se certificar que:
- Seu código esteja certo;
- Você não tenha esquecido de sincronizar locais menos óbvios;
- Não seja uma situação de exceção (como tentar dar getSelected() numa lista que não tem elemento selecionado).
Tente também seguir o stack trace, e ver o pq da exceção.
Valeu mas resolvi abdicar dos recursos da Collection para usar recursos primitivos !
No caso em questão eu fazia o seguinte !
Quando o botão que disparava a thread era executado ele pegava os índices dos objetos selecionados e então copiava esses objetos para um ListIterator.De acordo com que o iterator era percorrido no momento do changeList() ele pedia pra jList devolver o indice daquele objeto e então fazia o cambio. Não se existe falha nessa lógica . Decidi usar o ListIterator ao invés do Iterator pelo recurso do previous(), se é que eu também não sei se existe alguma diferença relevante entre eles para o fato em questão (o previous() era fundamental para atender a uma interação com o usuário na qual ele pode optar por persistir em caso de erros).
o erro era disparado aqui :
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return (E)elementData[index];
}
Bem , principalmente por questão de tempo eu não pude investigar o real motivo da causa !
mudei o esquema pro bom e velho laço FOR !
Saberia me dize se perco em algum ponto por causa disso ?
Eu me acostumei tanto a usar Iterator nas classes collection que
nem parei pra pensar nisso !
Você tem perdas se sua lista for um LinkedList.
Mas o que você fez você somente está escondendo um problema real. Se eu fosse você, mantinha o iterator e procurava mesmo sincronizar direto o seu programa.
É melhor ter um comportamento mais determinístico e problemático do que um erro que age silenciosamente, e vai só aparecer esporadicamente, nas mãos do seu cliente.
Kra , você tem mesmo razão !
vai ser preciso uma analise mais minuciosa !
ja passei por muita coisa pior , e provavelmente vou acabar
conseguindo resolver isso , pensando bem , vai valer a pena
tentar, valeu pelas dicas .
Geralmente, basta sincronizar os trechos onde a lista é acessada.
Se está difícil identificar todos os pontos, crie uma classe que encapsula essa lista, dê a ela os métodos necessários e troque a lista por essa classe.
Aí fica garantido.

Acho que solucionei o problema !
Na verdade eu sabia o que fazer , tanto é que eu postei o código aqui no tópico do jeito certo !
Acho que meu sub-quociente esta mais atento que eu ! :lol:
Eu juro que não me lembro de edita-lo pra postar , é até engraçado , mas não sei porque eu estava
dando repaint() nas jList !
o código na verdade era assim :
public void rebuildjList1()
{
jList1.setListData(data);
jList1.repaint();
}
public void rebuildjList2()
{
jList2.setListData(data2);
jList1.repaint();
}
Fiz um bom numero de testes e aparentemente o erro sumiu ! além do mais faz sentido
que enquanto a minha thread movia os elementos a thread AWT tentava repintar os componetes !
acredito que era ai onde ocorria a divergência , pois provavelmente a AWT ficava pra trás !
e entrava no Vector atrasada , como você bem relembrou isso poderia ocorrer
no meio de uma remoção da outra thread .
OBS : Putzz que cagada eu tava fazendo ,pior do que eu pensava , acabei de ver um absurdo maior ainda que passou batido , a Jlist1 tava recebendo repaint 2 vezes , um em cada rebuild!
Kra valeu mesmo , se você não me desse um toque pra insistir em encontrar o problema ia ficar esse
erro grotesco programa , sabe-se lá quando eu iria notar isso !
PARABÉNS!
E isso está se tornando um hábito cada vez maior, pelo que vejo aqui no GUJ e em outros fóruns. O programador, ao invés de entender e corrigir o problema, tenta contorna-lo, sem entender exatamente os fatores que levaram ao erro. Já vi muita gente aqui no GUJ fazendo isso, e muita gente até sugerindo uma resolução de dúvida com gambis desse tipo…
É uma prática que leva a programas instáveis e difíceis de corrigir. Afinal, vc está trocando um erro evidente por um obscuro… Uma péssima troca, diga-se de passagem.
A gente tem sempre que lembrar que quem mais usa o nosso sistema é o cliente. E, portanto, é com ele que esse erro vai se manifestar… E aí, será pressão do chefe, horas extras e noites perdidas de sono (quem mandou vc deixar o erro menos evidente, bobão?). Realmente não vale a pena.
Mas parabéns cara! O único jeito de aprender bem threads é com pepinos como esse… não se engane…
eu já perdi muitas noites de sono com bugs sinistros causados pelo paralelismo.