J'ai un programme suivant:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class SimpleWaitNotify implements Runnable { final static Object obj = new Object(); static boolean value = true; public synchronized void flag() { System.out.println("Before Wait"); try { obj.wait(); } catch (InterruptedException e) { System.out.println("Thread interrupted"); } System.out.println("After Being Notified"); } public synchronized void unflag() { System.out.println("Before Notify All"); obj.notifyAll(); System.out.println("After Notify All Method Call"); } public void run() { if (value) { flag(); } else { unflag(); } } public static void main(String[] args) throws InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(4); SimpleWaitNotify sWait = new SimpleWaitNotify(); pool.execute(sWait); SimpleWaitNotify.value = false; SimpleWaitNotify sNotify = new SimpleWaitNotify(); pool.execute(sNotify); pool.shutdown(); }
3 Réponses :
Vous appelez Afin d'attendre ou de notifier, vous devez «posséder» le moniteur d'abord. Signalez les méthodes et synchronisez-la à la place: P> attendre code> et
notifier code> sur
obj code>, mais vous synchronisez sur
ceci code> (car Vous avez des méthodes synchronisées).
public void flag() {
System.out.println("Before Wait");
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
}
System.out.println("After Being Notified");
}
public void unflag() {
System.out.println("Before Notify All");
synchronized (obj) {
obj.notifyAll();
}
System.out.println("After Notify All Method Call");
}
Super. Peut faire la même chose à se débarrasser de l'objet composite obj code> complètement?
@MADDY: Vous devriez être capable d'attendre et de notifier sur "Ceci" - mais c'est généralement une mauvaise idée, car "ceci" est généralement une référence que l'autre code a accès, efficacement. Garder une référence privée à un objet que seul votre code sait que votre code est une bonne pratique.
soit Par exemple, P> synchroniser code> sur
obj code> ou appelez
attendre code> et
notifier code> sur
Ça code> . Le thread d'appel doit contenir le moniteur de l'objet même em> sur lequel ces méthodes sont appelées.
class SimpleWaitNotify implements Runnable {
private final Object lock;
private final boolean wait;
SimpleWaitNotify(Object lock, boolean wait) {
this.lock = lock;
this.wait = wait;
}
public void flag() {
synchronized (lock) {
System.out.println("Before Wait");
try {
lock.wait();
System.out.println("After Being Notified");
} catch (InterruptedException ex) {
System.out.println("Thread interrupted");
}
}
}
public void unflag() {
synchronized(lock) {
System.out.println("Before Notify All");
lock.notifyAll();
System.out.println("After Notify All Method Call");
}
}
public void run() {
if (wait) {
flag();
} else {
unflag();
}
}
public static void main(String[] argv) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(4);
Object shared = new Object();
SimpleWaitNotify sWait = new SimpleWaitNotify(shared, true);
pool.execute(sWait);
SimpleWaitNotify sNotify = new SimpleWaitNotify(shared, false);
pool.execute(sNotify);
pool.shutdown();
}
}
J'ai changé plutôt pour attendre l'objet simple de l'accès lui-même. Cependant, dans ce cas, le programme ne s'arrête pas. Le fil suspendu n'est plutôt pas notifié. Je reçois l'imprimé suivant. Avant d'attendre avant de notifier tout après notifier tout appel de méthode
Plutôt mettre l'énoncé direct piscine.shutdown () code>, essayez comme ci-dessous.
while (!service.isTerminated())
{
service.shutdown();
}