I read somewhere that starting a thread has some special effect on the happend before relationship. Now I'm not sure if my code gurantees the happend before relationship, so please enlighten me.
I have a Dispatcher thread and a Worker class implementing the Runnable
interface. The Dispatcher thread creates a new instance of the Worker and fills a LinkedList
in the Worker instance through the add
method with elements.
Then the Dispatcher hands the Worker instance to a ExecutorService
via the execute
method.
Then the run method in the Worker class starts accessing and removing stuff from the LinkedList
.
Does the freshly started instance of the Worker see the same state of the LinkedList
as the Dispatcher left it in? Or could it be that LinkedList
is in some inconsitent state? Will I have to fill the LinkedList
in a sychronized method?
The Java Language Specification writes:
An action that starts a thread synchronizes-with the first action in the thread it starts.
If an action
x
synchronizes-with a following actiony
, then we also havehb(x, y)
.If we have two actions
x
andy
, we writehb(x, y)
to indicate thatx
happens-beforey
.
However, from your description it is not clear whether that is relevant in your case, as you talk about an executor, but don't explain when that executor is created or its worker threads started.
What is relevant is the following exerpt from Executor's JavaDoc:
Memory consistency effects: Actions in a thread prior to submitting a
Runnable
object to anExecutor
happen-before its execution begins, perhaps in another thread.
Hence your code is safe, as long as the dispatcher thread no longer accesses the list after submitting the Runnable
.
According to the documentations: ExecuterService javadocs
Memory consistency effects: Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task, which in turn happen-before the result is retrieved via Future.get().
This means that your concept is correct.
If there is locking or other synchronization primitives used, and you're just using a plain old ArrayList, then the two threads could see different states.
When coordinating work between two separate threads, you have to either use a thread-safe/concurrent data structure or use synchronization code to guarantee a consistent "memory snapshot" between the threads.
One of the reasons this is important is due to caching. The two threads, executing concurrently on different processors, could have cached some objects in different local registers (that are local to those processors).
来源:https://stackoverflow.com/questions/7651226/java-happend-before-thread-start