De thread en Java: Comment verrouiller un objet?
La Fonction suivante est en cours d'exécution dans son propre thread:
private void doSendData()
{
try {
//writeToFile(); //just a temporary location of a call
InetAddress serverAddr = InetAddress.getByName(serverAddress);
serverAddr.wait(60000);
//Log.d("TCP", "C: Connecting...");
Socket socket = new Socket(serverAddr, portNumber);
socket.setSoTimeout(3000);
try {
//Log.d("TCP", "C: Sending: '" + message + "'");
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
String message = packData();
out.println(message);
Log.d("TCP", "C: Sent.");
Log.d("TCP", "C: Done.");
connectionAvailable = true;
} catch(Exception e) {
Log.e("TCP", "S: Error", e);
connectionAvailable = false;
} finally {
socket.close();
announceNetworkAvailability(connectionAvailable);
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
announceNetworkAvailability(connectionAvailable);
}
}
Lors de l'exécution atteint la ligne serverAddr.wait(60000)
il déclenche une Exception:
java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Personne ne sait comment verrouiller un objet ou une fonction afin d'éviter la simultanéité?
J'ai essayé d'ajouter un Verrou de l'objet:
private final Lock lock = new ReentrantLock();
et la ligne
boolean locked = lock.tryLock();
au début de la fonction, mais ça ne fonctionne pas.
- Que voulez-vous faire? L'ATTENTE n'a aucun sens...
Vous devez vous connecter pour publier un commentaire.
Pour faire un appel à wait() sur un objet, vous devez maintenir la synchronisation de verrou sur l'objet (si le verrou est réellement libérée tandis que le thread est en attente):
Je dois avouer que pourquoi vous êtes désireux de le faire me déroute dans ce cas...
Peut-être la méthode que vous cherchez est Fil de discussion.sleep(long)? Cette méthode attendre (comme dans l'arrêt de l'exécution du thread) pour le temps spécifié en millisecondes, avant de reprendre.
objet.attendre(longtemps) (qui est ce que vous utilisez) fait quelque chose d'entièrement différent. Il attend un autre objet à partir d'un autre thread pour l'informer de la (ie: envoyer une sorte de message de réveil), et attendre au plus le nombre de millisecondes spécifié. Étant donné que le code que vous avez posté, je doute fortement de ce est ce que vous voulez vraiment.
Si Thread.sleep() n'est pas ce que vous voulez, alors vous devriez utiliser la synchronisation de bloc, comme mentionné par d'autres affiches.
J'ai toujours grincer des dents quand je vois ce genre de code. Faites-vous une faveur et regarder le
java.util.concurrent
paquet.Pour éviter ce message d'erreur, utilisez le mot-clé synchronized:
Le ci-dessus sont correctes. Vous pouvez utiliser en parallèle, un bloc de code. Ou vous pouvez créer ce qu'ils appellent un mutex. Un mutex peut effectivement être n'importe quel objet. Beaucoup de gens simplement utiliser de l'Objet lui-même comme un mutex. Ensuite, vous pouvez verrouiller le mutex. Tous les threads qui veulent obtenir l'accès doit attendre que le thread en tenant le mutex pour le libérer.
Il a également été suggéré par Apocalisp. Je recommande également que vous regardez à la java.util.simultanées paquet.
En général, quand vous avez le programme multi-threadé en Java, vous devez verrouiller la variable partagée par l'aide de la synchronisation (mot-clé) puis à tout moment juste un thread peut accéder à la mémoire partagée.
Code ci-dessous devrait fonctionner.
Référence à cette documentation page pour plus de détails.
Si le thread actuel est déjà titulaire de la serrure, puis la cale compteur est incrémenté par un et la méthode retourne immédiatement.
Si le verrou est détenu par un autre thread le thread courant est désactivée pour fil le cadre de la planification et reste inactif jusqu'à ce que la serrure a été acquis, au moment où le verrouillage comte est un
Référer à cette question SE connaître les avantages de
lock
sursynchronization
:La synchronisation vs Verrouillage