Quelle est la méthode pour ne plus avoir ce thread en mémoire? Pour le
terminer comme un Object quelconque?
Quelle est la méthode pour ne plus avoir ce thread en mémoire? Pour le
terminer comme un Object quelconque?
Quelle est la méthode pour ne plus avoir ce thread en mémoire? Pour le
terminer comme un Object quelconque?
Le 13/09/2018 à 00:27, jp a écrit :Quelle est la méthode pour ne plus avoir ce thread en mémoire? Pour
le terminer comme un Object quelconque?
La façon, propre de faire cela est d'utiliser un drapeau (booleen).
Tu remplace le while(true) par while(drapeau), et pour stopper tu
passes le drapeau à faux et envoie une interruption (interrupt()) au
thread pour le sortir d'un eventuel object.wait() ou autre appel
d'entrée/sortie sur lequel il serait coincé.
Le 13/09/2018 à 00:27, jp a écrit :
> Quelle est la méthode pour ne plus avoir ce thread en mémoire? Pour
> le terminer comme un Object quelconque?
La façon, propre de faire cela est d'utiliser un drapeau (booleen).
Tu remplace le while(true) par while(drapeau), et pour stopper tu
passes le drapeau à faux et envoie une interruption (interrupt()) au
thread pour le sortir d'un eventuel object.wait() ou autre appel
d'entrée/sortie sur lequel il serait coincé.
Le 13/09/2018 à 00:27, jp a écrit :Quelle est la méthode pour ne plus avoir ce thread en mémoire? Pour
le terminer comme un Object quelconque?
La façon, propre de faire cela est d'utiliser un drapeau (booleen).
Tu remplace le while(true) par while(drapeau), et pour stopper tu
passes le drapeau à faux et envoie une interruption (interrupt()) au
thread pour le sortir d'un eventuel object.wait() ou autre appel
d'entrée/sortie sur lequel il serait coincé.
Le Thu, 13 Sep 2018 00:41:19 +0200 Samuel DEVULDER
a écrit :La façon, propre de faire cela est d'utiliser un drapeau (booleen). Tu
remplace le while(true) par while(drapeau), et pour stopper tu passes
le drapeau à faux et envoie une interruption (interrupt()) au thread
pour le sortir d'un eventuel object.wait() ou autre appel
d'entrée/sortie sur lequel il serait coincé.
La modification et la lecture de la valeur devraient également se
trouver dans des blocs synchronisés (par exemple des fonctions marquées
synchronized), pour être sûr que la valeur a bien été partagée entre les
fils d'exécution.
Le Thu, 13 Sep 2018 00:41:19 +0200 Samuel DEVULDER
<samuel.devulder@laposte-dot-net.invalid> a écrit :
La façon, propre de faire cela est d'utiliser un drapeau (booleen). Tu
remplace le while(true) par while(drapeau), et pour stopper tu passes
le drapeau à faux et envoie une interruption (interrupt()) au thread
pour le sortir d'un eventuel object.wait() ou autre appel
d'entrée/sortie sur lequel il serait coincé.
La modification et la lecture de la valeur devraient également se
trouver dans des blocs synchronisés (par exemple des fonctions marquées
synchronized), pour être sûr que la valeur a bien été partagée entre les
fils d'exécution.
Le Thu, 13 Sep 2018 00:41:19 +0200 Samuel DEVULDER
a écrit :La façon, propre de faire cela est d'utiliser un drapeau (booleen). Tu
remplace le while(true) par while(drapeau), et pour stopper tu passes
le drapeau à faux et envoie une interruption (interrupt()) au thread
pour le sortir d'un eventuel object.wait() ou autre appel
d'entrée/sortie sur lequel il serait coincé.
La modification et la lecture de la valeur devraient également se
trouver dans des blocs synchronisés (par exemple des fonctions marquées
synchronized), pour être sûr que la valeur a bien été partagée entre les
fils d'exécution.
Le Thu, 13 Sep 2018 01:20:22 +0200, Yliur a écrit :Le Thu, 13 Sep 2018 00:41:19 +0200 Samuel DEVULDER
a écrit :La façon, propre de faire cela est d'utiliser un drapeau
(booleen). Tu remplace le while(true) par while(drapeau), et pour
stopper tu passes le drapeau à faux et envoie une interruption
(interrupt()) au thread pour le sortir d'un eventuel object.wait()
ou autre appel d'entrée/sortie sur lequel il serait coincé.
La modification et la lecture de la valeur devraient également se
trouver dans des blocs synchronisés (par exemple des fonctions
marquées synchronized), pour être sûr que la valeur a bien été
partagée entre les fils d'exécution.
Ok,merci! Si j'envoie une interruption interrupt() cela va stopper ma
boucle immédiatement? Parceque le bloc while(true){code} peut être
très long dans mon cas... Plusieurs minutes ou dizaines de minutes.
Je voudrais le terminer tout de suite et ne pas attendre que la
valeur while (condition) soit traitée.
Dans un bouquin on me conseille de faire:
try {
while(true){
if (interrupted()) return;
}
} catch (InterruptedExeption e){return;}
Je vais tester pour voir. Merci de vos réponses.
Le Thu, 13 Sep 2018 01:20:22 +0200, Yliur a écrit :
> Le Thu, 13 Sep 2018 00:41:19 +0200 Samuel DEVULDER
> <samuel.devulder@laposte-dot-net.invalid> a écrit :
>> La façon, propre de faire cela est d'utiliser un drapeau
>> (booleen). Tu remplace le while(true) par while(drapeau), et pour
>> stopper tu passes le drapeau à faux et envoie une interruption
>> (interrupt()) au thread pour le sortir d'un eventuel object.wait()
>> ou autre appel d'entrée/sortie sur lequel il serait coincé.
>
> La modification et la lecture de la valeur devraient également se
> trouver dans des blocs synchronisés (par exemple des fonctions
> marquées synchronized), pour être sûr que la valeur a bien été
> partagée entre les fils d'exécution.
Ok,merci! Si j'envoie une interruption interrupt() cela va stopper ma
boucle immédiatement? Parceque le bloc while(true){code} peut être
très long dans mon cas... Plusieurs minutes ou dizaines de minutes.
Je voudrais le terminer tout de suite et ne pas attendre que la
valeur while (condition) soit traitée.
Dans un bouquin on me conseille de faire:
try {
while(true){
if (interrupted()) return;
}
} catch (InterruptedExeption e){return;}
Je vais tester pour voir. Merci de vos réponses.
Le Thu, 13 Sep 2018 01:20:22 +0200, Yliur a écrit :Le Thu, 13 Sep 2018 00:41:19 +0200 Samuel DEVULDER
a écrit :La façon, propre de faire cela est d'utiliser un drapeau
(booleen). Tu remplace le while(true) par while(drapeau), et pour
stopper tu passes le drapeau à faux et envoie une interruption
(interrupt()) au thread pour le sortir d'un eventuel object.wait()
ou autre appel d'entrée/sortie sur lequel il serait coincé.
La modification et la lecture de la valeur devraient également se
trouver dans des blocs synchronisés (par exemple des fonctions
marquées synchronized), pour être sûr que la valeur a bien été
partagée entre les fils d'exécution.
Ok,merci! Si j'envoie une interruption interrupt() cela va stopper ma
boucle immédiatement? Parceque le bloc while(true){code} peut être
très long dans mon cas... Plusieurs minutes ou dizaines de minutes.
Je voudrais le terminer tout de suite et ne pas attendre que la
valeur while (condition) soit traitée.
Dans un bouquin on me conseille de faire:
try {
while(true){
if (interrupted()) return;
}
} catch (InterruptedExeption e){return;}
Je vais tester pour voir. Merci de vos réponses.
Les questions importantes à te poser pour choisir comment faire :
- Est-ce que tu veux couper ton fil d'exécution en pleine action,
vraiment n'importe quand ?
- Est-ce qu'il ne risque pas de laisser des données (visibles en
dehors du fil) dans un état incohérent ?
- Est-ce que le fil exécute une boucle dans laquelle il passe très
souvent et obligatoirement à un endroit donné du code ?
- Est-ce que le fil est parfois bloqué (appel à sleep pour un long
moment, attente d'une connexion réseau, ...) ?
Les questions importantes à te poser pour choisir comment faire :
- Est-ce que tu veux couper ton fil d'exécution en pleine action,
vraiment n'importe quand ?
- Est-ce qu'il ne risque pas de laisser des données (visibles en
dehors du fil) dans un état incohérent ?
- Est-ce que le fil exécute une boucle dans laquelle il passe très
souvent et obligatoirement à un endroit donné du code ?
- Est-ce que le fil est parfois bloqué (appel à sleep pour un long
moment, attente d'une connexion réseau, ...) ?
Les questions importantes à te poser pour choisir comment faire :
- Est-ce que tu veux couper ton fil d'exécution en pleine action,
vraiment n'importe quand ?
- Est-ce qu'il ne risque pas de laisser des données (visibles en
dehors du fil) dans un état incohérent ?
- Est-ce que le fil exécute une boucle dans laquelle il passe très
souvent et obligatoirement à un endroit donné du code ?
- Est-ce que le fil est parfois bloqué (appel à sleep pour un long
moment, attente d'une connexion réseau, ...) ?
Le Thu, 13 Sep 2018 07:31:48 +0200, Yliur a écrit :- Est-ce que le fil exécute une boucle dans laquelle il passe
très souvent et obligatoirement à un endroit donné du code ?
Il n'exécute qu'une boucle...- Est-ce que le fil est parfois bloqué (appel à sleep pour un
long moment, attente d'une connexion réseau, ...) ?
... mais qui est très longue. C'est pour ça que je n'ai pas envie
d'attendre que le test de la condition dans le while s'exécute. Je
veux terminer tout de suite et proprement.
- Est-ce qu'il ne risque pas de laisser des données (visibles en
dehors du fil) dans un état incohérent ?
Je peux l'éviter car ce n'est pas un thread compliqué. Il n'y a qu'un
paramètre à prendre en compte. C'est un thread qui allume et éteint
un relai. Il suffit juste de le mettre sur off avant de terminer le
thread.
Autre question: Si je fais Thread t = new Thread(); quelque part dans
le programme et que je fais autre part if(t.isAlive()){code qui
éteint le thread} est-ce que c'est correct et est-ce que ça génère
une erreur si t n'existe pas encore?
Le Thu, 13 Sep 2018 07:31:48 +0200, Yliur a écrit :
> - Est-ce que le fil exécute une boucle dans laquelle il passe
> très souvent et obligatoirement à un endroit donné du code ?
Il n'exécute qu'une boucle...
> - Est-ce que le fil est parfois bloqué (appel à sleep pour un
> long moment, attente d'une connexion réseau, ...) ?
... mais qui est très longue. C'est pour ça que je n'ai pas envie
d'attendre que le test de la condition dans le while s'exécute. Je
veux terminer tout de suite et proprement.
> - Est-ce qu'il ne risque pas de laisser des données (visibles en
> dehors du fil) dans un état incohérent ?
Je peux l'éviter car ce n'est pas un thread compliqué. Il n'y a qu'un
paramètre à prendre en compte. C'est un thread qui allume et éteint
un relai. Il suffit juste de le mettre sur off avant de terminer le
thread.
Autre question: Si je fais Thread t = new Thread(); quelque part dans
le programme et que je fais autre part if(t.isAlive()){code qui
éteint le thread} est-ce que c'est correct et est-ce que ça génère
une erreur si t n'existe pas encore?
Le Thu, 13 Sep 2018 07:31:48 +0200, Yliur a écrit :- Est-ce que le fil exécute une boucle dans laquelle il passe
très souvent et obligatoirement à un endroit donné du code ?
Il n'exécute qu'une boucle...- Est-ce que le fil est parfois bloqué (appel à sleep pour un
long moment, attente d'une connexion réseau, ...) ?
... mais qui est très longue. C'est pour ça que je n'ai pas envie
d'attendre que le test de la condition dans le while s'exécute. Je
veux terminer tout de suite et proprement.
- Est-ce qu'il ne risque pas de laisser des données (visibles en
dehors du fil) dans un état incohérent ?
Je peux l'éviter car ce n'est pas un thread compliqué. Il n'y a qu'un
paramètre à prendre en compte. C'est un thread qui allume et éteint
un relai. Il suffit juste de le mettre sur off avant de terminer le
thread.
Autre question: Si je fais Thread t = new Thread(); quelque part dans
le programme et que je fais autre part if(t.isAlive()){code qui
éteint le thread} est-ce que c'est correct et est-ce que ça génère
une erreur si t n'existe pas encore?
Là l'élément important c'est est-ce que la boucle est très longue parce
qu'elle réalise un traitement actif (des instructions sont exécutées en
permanence) ou bien elle est longue parce que le fil est bloqué à
différents moment ?
Dans le deuxième cas, quelles sont les opérations bloquantes ? Il y a
des chances pour qu'elles répondent aux interruptions des fils
d'exécution via la mécanique de java (interrupt()).
Suivant ton cas, j'essaierai d'expliquer plus en détail ce que tu peux
faire. La doc plus complète sur le sujet se trouve ici, mais c'est un
peu touffu :) :
<https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/
Il faudra bien faire attention quand même :
- Ne pas détruire le fil brutalement (avec Thread.stop(), qui de
toutes façons est obsolète).
- Utiliser un try/finally, pour être sûr que la finalisation soit
réalisée.
Suivant ce que tu veux dire par "n'existe pas" :
- Si tu n'as pas initialisé la variable (elle vaut null) : non, tu
vas avoir une NullPointException.
- Si le fil n'a simplement pas été lancé (via start()) : oui,
d'après la doc
(<https://docs.oracle.com/javase/6/docs/api/java/lang/
(le fil est en vie s'il a été démarré mais n'est pas encore mort)
Là l'élément important c'est est-ce que la boucle est très longue parce
qu'elle réalise un traitement actif (des instructions sont exécutées en
permanence) ou bien elle est longue parce que le fil est bloqué à
différents moment ?
Dans le deuxième cas, quelles sont les opérations bloquantes ? Il y a
des chances pour qu'elles répondent aux interruptions des fils
d'exécution via la mécanique de java (interrupt()).
Suivant ton cas, j'essaierai d'expliquer plus en détail ce que tu peux
faire. La doc plus complète sur le sujet se trouve ici, mais c'est un
peu touffu :) :
<https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/
Il faudra bien faire attention quand même :
- Ne pas détruire le fil brutalement (avec Thread.stop(), qui de
toutes façons est obsolète).
- Utiliser un try/finally, pour être sûr que la finalisation soit
réalisée.
Suivant ce que tu veux dire par "n'existe pas" :
- Si tu n'as pas initialisé la variable (elle vaut null) : non, tu
vas avoir une NullPointException.
- Si le fil n'a simplement pas été lancé (via start()) : oui,
d'après la doc
(<https://docs.oracle.com/javase/6/docs/api/java/lang/
(le fil est en vie s'il a été démarré mais n'est pas encore mort)
Là l'élément important c'est est-ce que la boucle est très longue parce
qu'elle réalise un traitement actif (des instructions sont exécutées en
permanence) ou bien elle est longue parce que le fil est bloqué à
différents moment ?
Dans le deuxième cas, quelles sont les opérations bloquantes ? Il y a
des chances pour qu'elles répondent aux interruptions des fils
d'exécution via la mécanique de java (interrupt()).
Suivant ton cas, j'essaierai d'expliquer plus en détail ce que tu peux
faire. La doc plus complète sur le sujet se trouve ici, mais c'est un
peu touffu :) :
<https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/
Il faudra bien faire attention quand même :
- Ne pas détruire le fil brutalement (avec Thread.stop(), qui de
toutes façons est obsolète).
- Utiliser un try/finally, pour être sûr que la finalisation soit
réalisée.
Suivant ce que tu veux dire par "n'existe pas" :
- Si tu n'as pas initialisé la variable (elle vaut null) : non, tu
vas avoir une NullPointException.
- Si le fil n'a simplement pas été lancé (via start()) : oui,
d'après la doc
(<https://docs.oracle.com/javase/6/docs/api/java/lang/
(le fil est en vie s'il a été démarré mais n'est pas encore mort)
Le Fri, 14 Sep 2018 05:46:30 +0200, Yliur a écrit :Là l'élément important c'est est-ce que la boucle est très longue
parce qu'elle réalise un traitement actif (des instructions sont
exécutées en permanence) ou bien elle est longue parce que le fil
est bloqué à différents moment ?
Il y a deux delay à l'intérieur d la boucle infinie qui peuvent durer
plusieurs minutes chacun.Dans le deuxième cas, quelles sont les opérations bloquantes ? Il y
a des chances pour qu'elles répondent aux interruptions des fils
d'exécution via la mécanique de java (interrupt()).
Je ne sais pas... Je vais essayer de remplacer les delay, qui sont
des méthodes implémentées par l'API spécifique que j'utilise, par des
Thread.sleep(n); pour voir...Suivant ton cas, j'essaierai d'expliquer plus en détail ce que tuthreadPrimitiveDeprecation.html>
peux faire. La doc plus complète sur le sujet se trouve ici, mais
c'est un peu touffu :) :
<https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/
Merci pour le lien. En fait ce que je veux faire est simple. J'ai une
carte qui comporte 4 relais branchée sur un raspberry. J'utilise une
bibliothèque écrite en C et une API écrite en Java qui utilise cette
bibliothèque. J'écris un petit programme qui mes les relais sur ON
pendant un certain nombre de secondes et sur OFF une autre durée.
Comme il y a 4 relais, j'ai créé 4 threads. J'arrive à allumer les
relais. J'arrive aussi à les éteindre. Mais par contre lorsque je
quitte le programme, les relais restent dans leur état. Quelquefois
sur ON et quelquefois sur OFF...
Il faut dire que je ne maitrise pas très bien les threads. Mais ce
que je veux faire n'est pas très compliqué. Je pense que je vais m'en
sortir.Il faudra bien faire attention quand même :
- Ne pas détruire le fil brutalement (avec Thread.stop(), qui de
toutes façons est obsolète).
- Utiliser un try/finally, pour être sûr que la finalisation
soit réalisée.
Je ne connais pas l'utilisation de try/finally mais je vais me
documenter sur ce sujet. Merci de m'avoir montré la direction dans
laquelle chercher.Suivant ce que tu veux dire par "n'existe pas" :Thread.html#isAlive()>)
- Si tu n'as pas initialisé la variable (elle vaut null) : non,
tu vas avoir une NullPointException.
- Si le fil n'a simplement pas été lancé (via start()) : oui,
d'après la doc
(<https://docs.oracle.com/javase/6/docs/api/java/lang/(le fil est en vie s'il a été démarré mais n'est pas encore
mort)
Si je fais un interrupt(), dans quel état se trouvera mon thread?
Est-ce qu'il sera encore actif? Ou est-ce qu'il sera égal à null?
Je reposte le code de mon thread:
-----début du code-----
import com.pi4j.wiringpi.*;
/**
*
* @author jp
*/
public class ShroomThread extends Thread {// throws
InterruptedException {
long ms_on, ms_off;
int pinmode;
//boolean isRunning = true;
ShroomThread( long on, long off, int pin ) {
this.ms_on = on;
this.ms_off = off;
this.pinmode = pin;
Gpio.pinMode( pinmode, Gpio.OUTPUT );
}
public void setGpioLow() {
Gpio.digitalWrite( pinmode, Gpio.LOW );
}
/**
*
*/
@Override
public void run() {
try {
while ( true ) {
if ( interrupted() ) {
throw new InterruptedException();
}
Gpio.digitalWrite( pinmode, Gpio.HIGH );
Gpio.delay( ms_on );
Gpio.digitalWrite( pinmode, Gpio.LOW );
Gpio.delay( ms_off );
}
}
catch ( InterruptedException e ) {}
}
}
-----fin du code-----
Dans la classe principale, je fais:
if ( t1 != null ) { t1.setGpioLow(); t1.interrupt(); }
ou bien:
if ( t1.isAlive() ) { t1.setGpioLow(); t1.interrupt(); }
Qu'est-ce qu'il vaut mieux?
A+
Le Fri, 14 Sep 2018 05:46:30 +0200, Yliur a écrit :
>
> Là l'élément important c'est est-ce que la boucle est très longue
> parce qu'elle réalise un traitement actif (des instructions sont
> exécutées en permanence) ou bien elle est longue parce que le fil
> est bloqué à différents moment ?
Il y a deux delay à l'intérieur d la boucle infinie qui peuvent durer
plusieurs minutes chacun.
>
> Dans le deuxième cas, quelles sont les opérations bloquantes ? Il y
> a des chances pour qu'elles répondent aux interruptions des fils
> d'exécution via la mécanique de java (interrupt()).
Je ne sais pas... Je vais essayer de remplacer les delay, qui sont
des méthodes implémentées par l'API spécifique que j'utilise, par des
Thread.sleep(n); pour voir...
>
> Suivant ton cas, j'essaierai d'expliquer plus en détail ce que tu
> peux faire. La doc plus complète sur le sujet se trouve ici, mais
> c'est un peu touffu :) :
> <https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/
threadPrimitiveDeprecation.html>
>
Merci pour le lien. En fait ce que je veux faire est simple. J'ai une
carte qui comporte 4 relais branchée sur un raspberry. J'utilise une
bibliothèque écrite en C et une API écrite en Java qui utilise cette
bibliothèque. J'écris un petit programme qui mes les relais sur ON
pendant un certain nombre de secondes et sur OFF une autre durée.
Comme il y a 4 relais, j'ai créé 4 threads. J'arrive à allumer les
relais. J'arrive aussi à les éteindre. Mais par contre lorsque je
quitte le programme, les relais restent dans leur état. Quelquefois
sur ON et quelquefois sur OFF...
Il faut dire que je ne maitrise pas très bien les threads. Mais ce
que je veux faire n'est pas très compliqué. Je pense que je vais m'en
sortir.
>
> Il faudra bien faire attention quand même :
> - Ne pas détruire le fil brutalement (avec Thread.stop(), qui de
> toutes façons est obsolète).
> - Utiliser un try/finally, pour être sûr que la finalisation
> soit réalisée.
Je ne connais pas l'utilisation de try/finally mais je vais me
documenter sur ce sujet. Merci de m'avoir montré la direction dans
laquelle chercher.
> Suivant ce que tu veux dire par "n'existe pas" :
> - Si tu n'as pas initialisé la variable (elle vaut null) : non,
> tu vas avoir une NullPointException.
> - Si le fil n'a simplement pas été lancé (via start()) : oui,
> d'après la doc
> (<https://docs.oracle.com/javase/6/docs/api/java/lang/
Thread.html#isAlive()>)
> (le fil est en vie s'il a été démarré mais n'est pas encore
> mort)
Si je fais un interrupt(), dans quel état se trouvera mon thread?
Est-ce qu'il sera encore actif? Ou est-ce qu'il sera égal à null?
Je reposte le code de mon thread:
-----début du code-----
import com.pi4j.wiringpi.*;
/**
*
* @author jp
*/
public class ShroomThread extends Thread {// throws
InterruptedException {
long ms_on, ms_off;
int pinmode;
//boolean isRunning = true;
ShroomThread( long on, long off, int pin ) {
this.ms_on = on;
this.ms_off = off;
this.pinmode = pin;
Gpio.pinMode( pinmode, Gpio.OUTPUT );
}
public void setGpioLow() {
Gpio.digitalWrite( pinmode, Gpio.LOW );
}
/**
*
*/
@Override
public void run() {
try {
while ( true ) {
if ( interrupted() ) {
throw new InterruptedException();
}
Gpio.digitalWrite( pinmode, Gpio.HIGH );
Gpio.delay( ms_on );
Gpio.digitalWrite( pinmode, Gpio.LOW );
Gpio.delay( ms_off );
}
}
catch ( InterruptedException e ) {}
}
}
-----fin du code-----
Dans la classe principale, je fais:
if ( t1 != null ) { t1.setGpioLow(); t1.interrupt(); }
ou bien:
if ( t1.isAlive() ) { t1.setGpioLow(); t1.interrupt(); }
Qu'est-ce qu'il vaut mieux?
A+
Le Fri, 14 Sep 2018 05:46:30 +0200, Yliur a écrit :Là l'élément important c'est est-ce que la boucle est très longue
parce qu'elle réalise un traitement actif (des instructions sont
exécutées en permanence) ou bien elle est longue parce que le fil
est bloqué à différents moment ?
Il y a deux delay à l'intérieur d la boucle infinie qui peuvent durer
plusieurs minutes chacun.Dans le deuxième cas, quelles sont les opérations bloquantes ? Il y
a des chances pour qu'elles répondent aux interruptions des fils
d'exécution via la mécanique de java (interrupt()).
Je ne sais pas... Je vais essayer de remplacer les delay, qui sont
des méthodes implémentées par l'API spécifique que j'utilise, par des
Thread.sleep(n); pour voir...Suivant ton cas, j'essaierai d'expliquer plus en détail ce que tuthreadPrimitiveDeprecation.html>
peux faire. La doc plus complète sur le sujet se trouve ici, mais
c'est un peu touffu :) :
<https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/
Merci pour le lien. En fait ce que je veux faire est simple. J'ai une
carte qui comporte 4 relais branchée sur un raspberry. J'utilise une
bibliothèque écrite en C et une API écrite en Java qui utilise cette
bibliothèque. J'écris un petit programme qui mes les relais sur ON
pendant un certain nombre de secondes et sur OFF une autre durée.
Comme il y a 4 relais, j'ai créé 4 threads. J'arrive à allumer les
relais. J'arrive aussi à les éteindre. Mais par contre lorsque je
quitte le programme, les relais restent dans leur état. Quelquefois
sur ON et quelquefois sur OFF...
Il faut dire que je ne maitrise pas très bien les threads. Mais ce
que je veux faire n'est pas très compliqué. Je pense que je vais m'en
sortir.Il faudra bien faire attention quand même :
- Ne pas détruire le fil brutalement (avec Thread.stop(), qui de
toutes façons est obsolète).
- Utiliser un try/finally, pour être sûr que la finalisation
soit réalisée.
Je ne connais pas l'utilisation de try/finally mais je vais me
documenter sur ce sujet. Merci de m'avoir montré la direction dans
laquelle chercher.Suivant ce que tu veux dire par "n'existe pas" :Thread.html#isAlive()>)
- Si tu n'as pas initialisé la variable (elle vaut null) : non,
tu vas avoir une NullPointException.
- Si le fil n'a simplement pas été lancé (via start()) : oui,
d'après la doc
(<https://docs.oracle.com/javase/6/docs/api/java/lang/(le fil est en vie s'il a été démarré mais n'est pas encore
mort)
Si je fais un interrupt(), dans quel état se trouvera mon thread?
Est-ce qu'il sera encore actif? Ou est-ce qu'il sera égal à null?
Je reposte le code de mon thread:
-----début du code-----
import com.pi4j.wiringpi.*;
/**
*
* @author jp
*/
public class ShroomThread extends Thread {// throws
InterruptedException {
long ms_on, ms_off;
int pinmode;
//boolean isRunning = true;
ShroomThread( long on, long off, int pin ) {
this.ms_on = on;
this.ms_off = off;
this.pinmode = pin;
Gpio.pinMode( pinmode, Gpio.OUTPUT );
}
public void setGpioLow() {
Gpio.digitalWrite( pinmode, Gpio.LOW );
}
/**
*
*/
@Override
public void run() {
try {
while ( true ) {
if ( interrupted() ) {
throw new InterruptedException();
}
Gpio.digitalWrite( pinmode, Gpio.HIGH );
Gpio.delay( ms_on );
Gpio.digitalWrite( pinmode, Gpio.LOW );
Gpio.delay( ms_off );
}
}
catch ( InterruptedException e ) {}
}
}
-----fin du code-----
Dans la classe principale, je fais:
if ( t1 != null ) { t1.setGpioLow(); t1.interrupt(); }
ou bien:
if ( t1.isAlive() ) { t1.setGpioLow(); t1.interrupt(); }
Qu'est-ce qu'il vaut mieux?
A+
Depuis l'extérieur :
- À moins que tu en aies vraiment besoin, tu devrais éviter d'avoir
des variables t1 == null, ça simplifierait tes problèmes. Mais ça
dépend de ce que tu veux faire avec des fils d'exécution.
- Je ne sais pas à quoi sert t1.setGpioLow(); : s'il s'agit du code
permettant de replacer le relais dans son état final, voir les
remarques ci-dessus.
- A priori le fil sera considéré comme mort une fois interrompu
(parce qu'il aura terminé l'exécution de sa méthode run).
Et donc t1.isAlive() reverra faux. D'après la doc, tu ne peux pas
relancer un fil qui s'est terminé (qui est mort), mais tu peux
toujours en recréer un via new ShroomThread (...).
- Lorsque le fil sera interrompu, la variable qui contient une
référence sur l'objet ShroomThread ne passera pas toute seule à
null. Donc t1 == null sera toujours faux.
Pour plus de précisions sur la gestion des fils depuis l'extérieur, il
faudrait savoir quel est le but exact de la manœuvre (est-ce que tu veux
parfois les relancer, dans quelles conditions, ... ?).
À propos du reste de ton code :
- Les classes ne déclarent pas d'exceptions, la ligne
throws InterruptedException (en commentaire) ne peut pas servir à
cet endroit.
- En général on définit les attributs des classes comme privés
(private int ...), ce qui évite d'y accéder malencontreusement
depuis l'extérieur.
Depuis l'extérieur :
- À moins que tu en aies vraiment besoin, tu devrais éviter d'avoir
des variables t1 == null, ça simplifierait tes problèmes. Mais ça
dépend de ce que tu veux faire avec des fils d'exécution.
- Je ne sais pas à quoi sert t1.setGpioLow(); : s'il s'agit du code
permettant de replacer le relais dans son état final, voir les
remarques ci-dessus.
- A priori le fil sera considéré comme mort une fois interrompu
(parce qu'il aura terminé l'exécution de sa méthode run).
Et donc t1.isAlive() reverra faux. D'après la doc, tu ne peux pas
relancer un fil qui s'est terminé (qui est mort), mais tu peux
toujours en recréer un via new ShroomThread (...).
- Lorsque le fil sera interrompu, la variable qui contient une
référence sur l'objet ShroomThread ne passera pas toute seule à
null. Donc t1 == null sera toujours faux.
Pour plus de précisions sur la gestion des fils depuis l'extérieur, il
faudrait savoir quel est le but exact de la manœuvre (est-ce que tu veux
parfois les relancer, dans quelles conditions, ... ?).
À propos du reste de ton code :
- Les classes ne déclarent pas d'exceptions, la ligne
throws InterruptedException (en commentaire) ne peut pas servir à
cet endroit.
- En général on définit les attributs des classes comme privés
(private int ...), ce qui évite d'y accéder malencontreusement
depuis l'extérieur.
Depuis l'extérieur :
- À moins que tu en aies vraiment besoin, tu devrais éviter d'avoir
des variables t1 == null, ça simplifierait tes problèmes. Mais ça
dépend de ce que tu veux faire avec des fils d'exécution.
- Je ne sais pas à quoi sert t1.setGpioLow(); : s'il s'agit du code
permettant de replacer le relais dans son état final, voir les
remarques ci-dessus.
- A priori le fil sera considéré comme mort une fois interrompu
(parce qu'il aura terminé l'exécution de sa méthode run).
Et donc t1.isAlive() reverra faux. D'après la doc, tu ne peux pas
relancer un fil qui s'est terminé (qui est mort), mais tu peux
toujours en recréer un via new ShroomThread (...).
- Lorsque le fil sera interrompu, la variable qui contient une
référence sur l'objet ShroomThread ne passera pas toute seule à
null. Donc t1 == null sera toujours faux.
Pour plus de précisions sur la gestion des fils depuis l'extérieur, il
faudrait savoir quel est le but exact de la manœuvre (est-ce que tu veux
parfois les relancer, dans quelles conditions, ... ?).
À propos du reste de ton code :
- Les classes ne déclarent pas d'exceptions, la ligne
throws InterruptedException (en commentaire) ne peut pas servir à
cet endroit.
- En général on définit les attributs des classes comme privés
(private int ...), ce qui évite d'y accéder malencontreusement
depuis l'extérieur.