IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

EDT/SwingWorker Java Discussion :

[SwingWorker] doInBackground() récursif = threads résiduels ?


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut [SwingWorker] doInBackground() récursif = threads résiduels ?
    Bonjour,

    J'utilise un SwingWorker pour effectuer un calcul qui peut être très long, ce calcul étant effectué de manière récursive dans la méthode doInBackground, qui est donc elle-même récursive. Voici la structure du code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    package PE;
    import java.beans.*;
    import javax.lang.model.type.NullType;
    import javax.swing.SwingWorker;
     
    public class Class4 extends SwingWorker<NullType,Integer> {
     
        private static int[] A;
        protected static boolean F = false;
        protected static boolean G = true;
     
        protected Class4(int[] a) {
            A = a;
            addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent H) {
                    if (getProgress() == 100 || Class3.I.isDone()) {
    // actions
                        if (getProgress() == 100) {
                            F = true;
                        }
                    }
                    if (F) {
                        Class3.H.setText("100 %");
                    }
                    else {
                        Class3.H.setText(String.valueOf(getProgress())+" %");
                    }
                }
            });
        }
     
        @Override
        protected NullType doInBackground() {
            if (this.isCancelled()) {
                new Class7(A[2],A[5],true);
            }
            else {
    //actions
                for (int i=0;i<A[5]-A[2];i++) {
                    for (int j=0;j<A[5]-A[2];j++) {
                        if (this.isCancelled()) {
                            j = A[5]-A[2];
                            i = A[5]-A[2];
                        }
                        else {
                            if (condition) {
    //actions
                                setProgress((int) progress);
                                publish(getProgress());
                            }
                            else {
                                j = A[5]-A[2];
                                i = A[5]-A[2];
    //modification des paramètres
                                doInBackground();
                            }
                        }
                    }
                }
            }
            if (this.isDone() == false && G) {
                G = false;
    // terminaison du calcul
            }
            return null;
        }
     
    }
    Ce code marche bien, même pour un calcul relativement long, mais s'il est très long, il s'arrête au bout d'un certain nombre d'appels à doInBackground(). J'observe par ailleurs un ralentissement du calcul au bout d'un certain nombre de récursions. Lorsque le calcul n'est pas trop long mais que doInBackground() est quand même rappelée un certain nombre de fois, donc quand condition == false, je dois de plus utiliser deux booléens F et G qui n'ont normalement pas lieu d'être :
    - F sert à ce que l'affichage reste à 100 % lorque le calcul est terminé car sinon il redescend à une valeur inférieure
    - G sert à ce que la terminaison du calcul ne s'effectue qu'une seule fois car sinon j'observe qu'elle est effectuée plusieurs fois

    Je pense donc que le n-ième doInBackground() ne s'arrête pas lorsque le (n+1)-ième est lancé, et ce jusqu'à planter le programme s'il y en a trop qui s'exécutent en même temps. Si une âme charitable voit un moyen de résoudre ce problème, je suis preneur.

    Merci d'avance

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut
    Je sais toujours pas pourquoi les dIBg s'accumulent. D'autre part je vais maximiser le heap size, mais étant donné que le programme est éventuellement destiné à être utilisé sur différentes machines, y'a-t-il un moyen de récupérer automatiquement le Xmx de la machine sur laquelle est installé le programme ?

  3. #3
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Salut,

    J'ai pas trop lu ton problème parce qu'a c't'heure là j'peux plus ! Mais ...

    Je ne sais pas trop si il est convenable d'appeler toi-même la méthode doInBackground() !

    As-tu essayé de créer TA méthode. Et plutôt que d'appeler récursivement doInBackground() d'appeler récursivement TA méthode.

    Si j'ai rien compris alors désolé

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut
    Salut,

    D'abord merci de d'intéresser à mon problème.
    J'ai effectivement esssayé de programmer une méthode récursive appelée une seule fois dans doInBackground(), mais le résultat est le même.
    Par contre j'ai augmenté le heap size au maximum des capacités de mon PC (1024Mo pour une RAM de 2048) et le programme marche pour l'instant. Enfin je dis ça, je l'ai lancé il y a environ 3 heures en lui demandant la résolution de 210 polynômes du 19ème degré (je sais, j'suis pas normal) et il en est à peu près à 50 %. S'il en a encore pour 3 heures, je vais aller dormir ailleurs parce qu'il fait un bruit que j'avais encore jamais entendu. En tout cas les threads n'ont pas l'air de s'arrêter quand ils devraient, qu'on les programment dans doInBackground() ou dans une méthode séparée. T'as une idée ?

  5. #5
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Je n'ai pas vraiment d'idée pour régler ton problème. Mais dans un premier je chercherais à vérifier mon code métier sans Thread (ou SwingWorker) ni UI. Lorsque je serais certain de ce code, je chercherais à l'intégrer a un SwingWorker ou un Thread.
    Bon courage !

  6. #6
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Il n'est pas très facile de comprendre ton code. Par exemple, if (condition) ? ...et je n'ai trouvé condition déclarée ou renseigné nulle part. Etc dans le genre.

    Je te conseille de revoir ton code en le rendant plus expressif. Cela t'aidera certainement à mieux maîtriser ce qu'il fait.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut
    "condition" était seulement là à titre indicatif pour montrer que l'appel récursif est dans une boucle if, mais n'est pas une variable en soi. Un code de ce genre renvoyait le bon résultat si ce n'est que les dIBg() semblaient s'accumuler pour les calculs de grande ampleur et faisaient ramer le PC. J'ai shunté le problème en modifiant le code de manière à ce que le prog renvoie le bon résultat sans utiliser de récursion (ce que j'aurais du faire dès le départ). Je ne sais donc pas si je peux marquer ce problème comme résolu, puisqu'il n'existe plus pour moi, mais il se pourrait que quelqu'un d'autre le rencontre un jour et je serais curieux de connaître la solution. Par contre je cherche toujours le moyen de récupérer la RAM disponible sur un PC, pour pouvoir adapter ce programme à différentes machines sans avoir à en créer plusieurs versions. Quoiqu'il en soit, je poste ici le code complet de Class4, en espérant que ce sera plus clair :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    package PE;
    import java.beans.*;
    import javax.lang.model.type.NullType;
    import java.math.*;
    import javax.swing.SwingWorker;
     
    public class Class4 extends SwingWorker<NullType,Integer> {
     
        private static int[] A;
        private static int[][] B;
        private static Class9 C;
        private static int D;
        private static int[][] E;
        private static boolean F = false;
        private static boolean G = true;
        private static final MathContext DECIMAL128 = new MathContext(34,RoundingMode.HALF_EVEN);
     
        protected Class4(int[] a,int[][] b,Class9 c,int d,int[][] e) {
            A = a;
            B = b;
            C = c;
            D = d;
            E = e;
            addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent G) {
                    if (getProgress() == 100 || Class3.I.isDone()) {
                        Class1.D.setEnabled(true);
                        Class3.F.setEnabled(true);
                        Class3.G.setEnabled(false);
                        if (getProgress() == 100) {
                            F = true;
                        }
                    }
                    if (F) {
                        Class3.H.setText("100 %");
                    }
                    else {
                        Class3.H.setText(String.valueOf(getProgress())+" %");
                    }
                }
            });
        }
     
        @Override
        protected NullType doInBackground() {
            if (this.isCancelled()) {
                new Class7(A[2],A[5],true);
            }
            else {
                int[][] H = new int[A[0]-1][A[5]-A[2]];
                int I = -1;
                for (int i=0;i<D;i++) {
                    if (this.isCancelled()) {
                        i = D;
                    }
                    else {
                        int J = 0;
                        for (int j=0;j<A[0]-1;j++) {
                            J = J+E[j][i];
                        }
                        if (J < A[4]+1) {
                            int K = 0;
                            if (A[2] != 0) {
                                for (int j=0;j<A[2];j++) {
                                int L = 0;
                                    for (int k=0;k<A[0]-1;k++) {
                                        if (E[k][i] == B[k][j]) {
                                            L++;
                                        }
                                    }
                                    if (L > K) {
                                        K = L;
                                    }
                                }
                            }
                            if (K != A[0]-1 || A[2] == 0) {
                                I++;
                                for (int j=0;j<A[0]-1;j++) {
                                    H[j][I] = E[j][i];
                                }
                            }
                        }
                        setProgress((int) (i+1)*100/(D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2])+1)+A[3]));
                        publish(getProgress());
                    }
                }
                if (this.isCancelled()) {
                    new Class7(A[2],A[5],true);
                }
                else {
                    Class9 M = new Class9(A[5]-A[2],A[3]);
                    for (int i=0;i<A[5]-A[2];i++) {
                        for (int j=0;j<A[3];j++) {
                            if (this.isCancelled()) {
                                j = A[3];
                                i = A[5]-A[2];
                            }
                            else {
                                M.setElement(new BigDecimal("1.0"),i,j);
                                for (int k=0;k<A[0];k++) {
                                    if (k < A[1]-1) {
                                        M.setElement(M.getElement(i,j).multiply(C.getElement(k,j).pow(H[k][i],DECIMAL128),DECIMAL128),i,j);
                                    }
                                    if (k > A[1]-1) {
                                        M.setElement(M.getElement(i,j).multiply(C.getElement(k,j).pow(H[k-1][i],DECIMAL128),DECIMAL128),i,j);
                                    }
                                }
                                setProgress((int) (D+A[3]*i+j+1)*100/(D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2])+1)+A[3]));
                                publish(getProgress());
                            }
                        }
                    }
                    if (this.isCancelled()) {
                        new Class7(A[2],A[5],true);
                    }
                    else {
                        Class9 N = new Class9(A[5]-A[2],A[5]-A[2]);
                        Class9 O = new Class9(A[5]-A[2],A[5]-A[2]);
                        for (int i=0;i<A[5]-A[2];i++) {
                            for (int j=0;j<A[5]-A[2];j++) {
                                if (this.isCancelled()) {
                                    j = A[5]-A[2];
                                    i = A[5]-A[2];
                                    new Class7(A[2],A[5],true);
                                }
                                else {
                                    for (int k=0;k<A[3];k++) {
                                        N.setElement(N.getElement(i,j).add(M.getElement(j,k).multiply(M.getElement(i,k),DECIMAL128)),i,j);
                                    }
                                    if (j >= i) {
                                        BigDecimal P = new BigDecimal("0.0");
                                        BigDecimal Q = new BigDecimal("0.0");
                                        for (int k=0;k<i;k++) {
                                            P = P.add(O.getElement(k,i).multiply(O.getElement(k,j),DECIMAL128));
                                            Q = Q.add(O.getElement(k,i).pow(2,DECIMAL128));
                                        }
                                        P = N.getElement(i,j).subtract(P);
                                        Q = N.getElement(i,i).subtract(Q);
                                        if (Q.signum() == 1) {
                                            if (j == i) {
                                                O.setElement(new BigDecimal(String.valueOf(Math.sqrt(Q.doubleValue()))),i,j);
                                            }
                                            if (j > i) {
                                                O.setElement(P.divide(new BigDecimal(String.valueOf(Math.sqrt(Q.doubleValue()))),DECIMAL128),i,j);
                                            }
                                            setProgress((int) (D+(A[5]-A[2])*(A[3]+i)+j+1)*100/(D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2])+1)+A[3]));
                                            publish(getProgress());
                                        }
                                        else {
                                            j = A[5]-A[2];
                                            A[2]++;
                                            if (A[2] == A[5]) {
                                                i = A[5]-A[2];
                                            }
                                            else {
                                                int[][] R = new int[A[0]-1][A[2]];
                                                for (int k=0;k<A[0]-1;k++) {
                                                    for (int l=0;l<A[2]-1;l++) {
                                                        R[k][l] = B[k][l];
                                                    }
                                                    R[k][A[2]-1] = H[k][i];
                                                }
                                                B = R;
                                                i = A[5]-A[2];
                                                doInBackground();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (this.isCancelled() == false) {
                             if (A[2] == A[5]) {
                                new Class7(A[2],A[5],false);
                            }
                            else {
                                Class9 S = new Class9(A[5]-A[2],A[5]-A[2]);
                                for (int i=0;i<A[5]-A[2];i++) {
                                    for (int j=0;j<A[5]-A[2];j++) {
                                        if (this.isCancelled()) {
                                            j = A[5]-A[2];
                                            i = A[5]-A[2];
                                        }
                                        else {
                                            if (j == i) {
                                                S.setElement(new BigDecimal("1.0").divide(O.getElement(j,i),DECIMAL128),j,i);
                                            }
                                            if (j > i) {
                                                for (int k=i;k<j;k++) {
                                                    S.setElement(S.getElement(j,i).subtract(S.getElement(k,i).multiply(O.getElement(k,j),DECIMAL128)),j,i);
                                                }
                                                S.setElement(S.getElement(j,i).divide(O.getElement(j,j),DECIMAL128),j,i);
                                            }
                                            setProgress((int) (D+(A[5]-A[2])*(A[3]+A[5]-A[2]+i)+j+1)*100/(D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2])+1)+A[3]));
                                            publish(getProgress());
                                        }
                                    }
                                }
                                if (this.isCancelled()) {
                                    new Class7(A[2],A[5],true);
                                }
                                else {
                                    Class9 T = new Class9(1,A[5]-A[2]);
                                    Class9 U = new Class9(1,A[3]);
                                    Class9 V = new Class9(A[5]-A[2],A[3]);
                                    Class9 W = new Class9(1,A[3]);
                                    Class9 X = new Class9(1,A[3]);
                                    BigDecimal Y = new BigDecimal("0.0");
                                    for (int i=0;i<A[3];i++) {
                                        if (this.isCancelled()) {
                                            i = A[3];
                                        }
                                        else {
                                            for (int j=0;j<A[5]-A[2];j++) {
                                                for (int k=0;k<A[5]-A[2];k++) {
                                                    for (int l=0;l<A[5]-A[2];l++) {
                                                        T.setElement(T.getElement(0,j).add(S.getElement(k,j).multiply(S.getElement(k,l),DECIMAL128).multiply(M.getElement(l,i),DECIMAL128).multiply(C.getElement(A[1]-1,i),DECIMAL128)),0,j);
                                                    }
                                                }
                                                U.setElement(U.getElement(0,i).add(M.getElement(j,i).multiply(T.getElement(0,j),DECIMAL128)),0,i);
                                                V.setElement((T.getElement(0,j).multiply(M.getElement(j,i),DECIMAL128)).abs(),j,i);
                                                W.setElement(W.getElement(0,i).add(V.getElement(j,i)),0,i);
                                            }
                                            X.setElement(C.getElement(A[1]-1,i).subtract(U.getElement(0,i)),0,i);
                                            Y = Y.add(X.getElement(0,i).pow(2,DECIMAL128));
                                            setProgress((int) (D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2]))+i+1)*100/(D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2])+1)+A[3]));
                                            publish(getProgress());
                                        }
                                    }
                                    if (this.isCancelled()) {
                                        new Class7(A[2],A[5],true);
                                    }
                                    else {
                                        Class9 Z = new Class9(1,A[5]-A[2]);
                                        String[] AA = new String[A[5]-A[2]];
                                        for (int i=0;i<A[5]-A[2];i++) {
                                            if (this.isCancelled()) {
                                                i = A[5]-A[2];
                                            }
                                            else {
                                                for (int j=0;j<A[3];j++) {
                                                    Z.setElement(Z.getElement(0,i).add(new BigDecimal("100.0").multiply(V.getElement(i,j),DECIMAL128).divide(new BigDecimal(String.valueOf(A[3])).multiply(W.getElement(0,j),DECIMAL128),DECIMAL128)),0,i);
                                                }
                                                BigDecimal AB = Y.multiply(S.getElement(i,i),DECIMAL128).pow(2,DECIMAL128).divide(new BigDecimal(String.valueOf(A[3]-A[5]+A[2]+1)),DECIMAL128);
                                                AA[i] = String.valueOf(Math.sqrt(AB.doubleValue()));
                                                setProgress((int) (D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2]))+A[3]+i+1)*100/(D+(A[5]-A[2])*(A[3]+2*(A[5]-A[2])+1)+A[3]));
                                                publish(getProgress());
                                            }
                                        }
                                        if (this.isCancelled()) {
                                            new Class7(A[2],A[5],true);
                                        }
                                        else {
                                            new Class5(A[0],A[1],A[2],A[5],B,H,T,Z,AA);
                                            new Class6(A[1],A[3],C,U,X);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return null;
        }
     
    }
    En le regardant, je ne comprends d'ailleurs pas comment ce code peut marcher puisque seul le premier dIBg() devrait entrer dans la boucle de terminaison (test sur G) et qu'ensuite G == false, alors que le seul dIBg() valable est le dernier (d'où la récursion), et qu'il ne devrait donc pas rentrer dans cette boucle. Pourtant les résultats sont bons . Y'a un truc qui m'échappe.

Discussions similaires

  1. SwingWorker.doInBackground() n'accomplit pas sa tache
    Par sofiene D dans le forum Général Java
    Réponses: 1
    Dernier message: 07/02/2010, 11h21
  2. Lancé un thread SwingWorker depuis un autre thread SwingWorker
    Par romuluslepunk dans le forum EDT/SwingWorker
    Réponses: 5
    Dernier message: 14/03/2009, 19h58
  3. Thread vs SwingWorker
    Par cho7 dans le forum EDT/SwingWorker
    Réponses: 12
    Dernier message: 16/01/2009, 00h05
  4. [SwingWorker] Thread.sleep(x) et done()
    Par SpecialCharacter dans le forum EDT/SwingWorker
    Réponses: 4
    Dernier message: 15/02/2008, 16h42
  5. SwingWorker Thread et JProgressBar
    Par keub51 dans le forum EDT/SwingWorker
    Réponses: 8
    Dernier message: 13/02/2008, 16h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo