Java: Concurrency inside ActionListener.actionPerformed
I started doing concurrency in Java today (maybe it was a bad idea ...)
I have read several articles about this. At first I figured it out, but now I'm confused ...
I'm going straight to the point. Suppose this class
public class Test implements ActionListener
{
private boolean bool;
public void process()
{
if (bool)
// ...
return bool;
}
@Override
public void actionPerformed(ActionEvent e)
{
// We can suppose that this method belongs to JButton or so...
// And if I am not wrong then this method is fired in EDT, so it means it runs in
// other thread (Event Dispatch Thread) in contrast with this class... So there are
// two threads...
bool = ... ? true : false;
}
// ...
}
My confusion:
In actionPerformed (), we change the value of the bool property , and at the same time we can access the property inside process () (again if I'm not mistaken) ... For me it seems like an error might occur or so ... Mine the solution is that the bool property should be volatile or the method () should be marked synchronized and the operator
bool = ... ? true : false;
should be as follows:
synchronized (this)
{
bool = ... ? true : false;
}
This is a little primitive example, but we can consider the bool property as Object, String, etc ... and in actionPerformed () we will set it to null and in process () a NullPointerException will be thrown ...
What do you think? I want to know why someone is using synchronization inside listeners ... I didn't find anyone ...
thank
Relationship brolinko
EDIT # 1: process () is never called in EDT ... When I create an instance of Test, for example in main () , then the instance is started inside the thread as main (), and in main (), I can call process (). .. So there are two threads in this case, if I'm not mistaken ...
source to share
You are not mistaken, if a variable is used by two or more threads, the entries must be made visible using the appropriate memory barriers (synchronized / volatile / java.util.concurrent).
In this case, however, the question arises: is it process()
not called from the EDT? If so, there are no high water streams to talk about, and hence the code works, albeit dangerously dangerous.
Update: You say it is (As @jtahlborn pointed out, this barrier still only applies to calls from EDT)process()
n't being called from EDT. Your code will still work because while you are not putting a memory barrier on your entry, the EDT implementation does . In theory, relying on this is a dangerous idea because there is no guarantee it will stay that way. In practice, there are so many fragile AWT applications out there that they are unlikely to change.
source to share
The Java memory model and Java multithreading rules apply to all classes and threads. The fact that your class implements an ActionListener doesn't matter.
If two threads access a shared variable and you expect the entries on one thread to be visible by reading from other threads, then some synchronization must be used to access the shared variable (synchronized access, make the variable mutable, or use a thread-safe object like AtomicBoolean) ...
source to share