Consider a snippet taken from here :
public class Event { }
public interface EventListener {
public void onEvent(Event e);
}
public class ThisEscape {
private final int num;
public ThisEscape(EventSource source) {
source.registerListener(new EventListener() {
@Override
public void onEvent(Event e) {
doSomething(e);
}
});
num = 42;
}
private void doSomething(Event e) {
if (num != 42) {
System.out.println("Race condition detected at " + new Date());
}
}
}
public class EventSource extends Thread {
private final BlockingQueue<EventListener> listeners =
new LinkedBlockingQueue<EventListener>();
public void run() {
while (true) {
try {
listeners.take().onEvent(null);
} catch (InterruptedException e) {
break;
}
}
}
public void registerListener(EventListener eventListener) {
listeners.add(eventListener);
}
}
public class ThisEscapeTest {
public static void main(String[] args) {
EventSource es = new EventSource();
es.start();
while (true) {
new ThisEscape(es);
}
}
}
For consolidation, we have 2 threads
In the event source stream there is a BlockingQueue to hold the EventListener. In the execution method for the same thread
The consumed EventSource thread continues to list objects from the lock queue and processes them. If the same thread tries to pull an object from an empty queue, the same thread is blocked until producing thread(Main thread) puts the object in the queue.
2 () , - - timimg, 2 , EventSource , num!= 2 , , .
source.registerListener(new EventListener() {
@Override
public void onEvent(Event e) {
doSomething(e);
}
});
num = 42;
}
, , .
( ), doSomething() ( EventSource) , , 2 . ?
public ThisEscape(EventSource source) {
synchronized(this){
source.registerListener(new EventListener() {
@Override
public void onEvent(Event e) {
doSomething(e);
}
});
num = 42;
}
}
- doSomething(), , ?
-, , , . . final ( private final int num = 42)?