[JAVA] SWT multithreading

Pagina: 1
Acties:

  • tweakerbee
  • Registratie: Maart 2000
  • Laatst online: 12-02 02:38
Ik ben aan de slag gegaan met SWT om een user interface te bouwen. Omdat er stukken code uitgevoerd worden die lang duren (indexeren van documenten mbv Lucene) wilde ik de boel multithreaden. Als je alles in een enkele thread houdt kun je namelijk je GUI niet fatsoenlijk updaten en lijkt hij te bevriezen tijdens indexeer acties.

Dit heb ik nu als volgt opgelost, maar ik heb een beetje het gevoel dat het een ranzige oplossing is, omdat ik een aantal variabelen final heb moeten maken of naar final variabelen heb gekopieerd. Je kunt niet gewoon uit een andere thread de UI-thread aanroepen overigens, dan gooit SWT een illegal thread access exception naar je hoofd. asyncExec en syncExec stonden in de JavaDocs beschreven als mogelijkheden om vanuit andere threads binnen de UI-thread iets uit te laten voeren.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    private static void indexDirectory(IndexWriter writer, File dir) throws Exception {
        final File[] files = dir.listFiles();
        final ProgressBar pgBar = swtUI.getProgressBar();
        final List list = swtUI.getList();
        
        swtUI.shell.getDisplay().syncExec( new Runnable() {
            public void run() {
                indexSubdirectories = swtUI.getIndexeerSubdirectoriesButton().getSelection();
            }
        });
        
        swtUI.shell.getDisplay().asyncExec (new Runnable () {
            public void run () {
                pgBar.setSelection(0);
            }
        });
        
        for(int i = 0; i < files.length; i++) {
            swtUI.shell.getDisplay().asyncExec (new Runnable () {
                public void run () {
                    pgBar.setMaximum(files.length);
                }
            });
            File f = files[i];

            if(f.isDirectory() && indexSubdirectories) {
                indexDirectory(writer,f);
                list.add("Indexeren van directory "+f.getName());
            }
            else if(f.getName().endsWith(".txt")) {
                indexTXTFile(writer,f);
            }
            else if(f.getName().endsWith(".pdf")) {
                indexPDFFile(writer,f);
            }
            else if(f.getName().endsWith(".html")) {
                indexHTMLFile(writer,f);
            }
            else if(f.getName().endsWith(".xml")) {
                indexXMLFile(writer,f);
            }
            final int j = i;
            swtUI.shell.getDisplay().asyncExec (new Runnable () {
                public void run () {
                    pgBar.setSelection(j+1);
                    pgBar.redraw();
                    list.redraw();
                }
            });

        }
    }


Het werkt wel, maar is vrij omslachtig, en ik vroeg me af of er betere manieren zijn. Uiteraard moet wel de GUI geupdate worden.

[ Voor 6% gewijzigd door tweakerbee op 20-07-2006 15:18 . Reden: code highlighting aan ]

You can't have everything. Where would you put it?


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

1) maak 'core' logica niet afhankelijk van je gui. Dit ontkoppelen met een eenvoudige layer of indirection: observer/observable.

2) in de implementatie van de observer, ga jij een job laten executen op de swt thread.

Java:
1
2
3
4
5
6
7
8
9
class SwtLuceneObserver implements LuceneObserver{
   void someEventOccurred(SomeEvent e){
       swtUI.shell.getDisplay().asyncExec(new Runnable()){
           void run(){
               someList.add("blabla");
           }
       };
   }
}


En dan doe jij in jouw lucene meuk:
Java:
1
2
3
4
if(f.isDirectory() && indexSubdirectories) {
                indexDirectory(writer,f);
                luceneObserver.someEventOccurred(new SomeEvent("Indexeren van directory "+f.getName()));
            } 

[ Voor 15% gewijzigd door Alarmnummer op 20-07-2006 16:58 ]


  • tweakerbee
  • Registratie: Maart 2000
  • Laatst online: 12-02 02:38
Thanks. Dit had ik al een beetje gedaan (maar dan ranziger) door een nieuwe void addToList() te maken waarin hetzelfde gebeurde. Dit lijkt me inderdaad makkelijker te onderhouden.

Kun je me trouwens een goed boek aanraden. Wil graag een goed boek erover gaan lezen, maar er zijn er teveel. JavaDocs helpen je een eind, maar een goed ontwerp leer je daardoor niet maken. En om nu het wiel helemaal zelf uit te gaan vinden...

You can't have everything. Where would you put it?


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

zoek op gof

[ Voor 10% gewijzigd door Alarmnummer op 20-07-2006 18:47 ]


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Dit is eigenlijk vrij trivaal, 'k weet niet of je er een boek over wil lezen maar de meeste java boeken die gui's behandelen, behandelen ook zeker zoiets als Model-View-Controller. MVC valt onder design patterns, en je kan beter misschien daar boeken over gaan zoeken.

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 11-02 10:20

Apache

amateur software devver

gof lijkt mij nogal onnodig zwaar, design patterns explained is een duidelijker boek, ook java voorbeelden tov c++ niet dat dat zoveel uitmaakt en het leest een heel pak leuker :)

algemene kennis van uml & modeleer technieken lijkt me ook handig voordat je met zoiets aan de slag gaat.

If it ain't broken it doesn't have enough features

Pagina: 1