Reputation: 684
I have class that looks like
public class Sender {
private LoggingAdapter log = Logging.getLogger(this.toString());
private final ArrayList<CSAMessage> sentHistory = new ArrayList<>();
public void send(final CSAMessage message) {
doSend(message);
sentHistory.add(message);
}
private void doSend(CSAMessage message) {
//do send stuff
}
}
The problem is - when two instances of Sender class are called in same time, they share private sentHistory field. In logs it looks like
Sender1 send(...) was called, message was added to own sendHistory list
Sender2 send(...) was called, message was added to Sender1 sendHistory list
How is that posiible? I'm shure that Sender1 and Sender2 are different instances, they called from different threads, but call was made in same time.
I already tried to make variable 'volatile' - no result
This block gives no result too
private final ArrayList<CSAMessage> sentHistory;
{
sentHistory = new ArrayList<>();
}
Only synchronizing via class helps
public void send(final CSAMessage message) {
synchronized (Sender.class) {
doSend(message);
sentHistory.add(message);
}
}
But this will be performance bottleneck - many Senders must be able to work in same time. And why should i do so? Different instances must use it's own variables!
There are also log variable that has been declared same way, but logging variable not shared between objects, every Sender write logs from it's own name.
Upvotes: 0
Views: 54
Reputation: 726809
Marking the variable final
and initializing it the way you did
private final ArrayList<CSAMessage> sentHistory = new ArrayList<>();
// ^^^^^ ^^^^^^^^^^^^^^^^^^^
makes it absolutely impossible for multiple instances to share the same ArrayList
.
What remains possible, however, is for multiple ArrayList
s to share the same instances of CSAMessage
. In cases when shared CSAMessage
s are mutable, it is possible to create an illusion of sharing. For example, if CSAMessage
has a link back to Sender
which is set as part of a send
call, making a change concurrently may present the message as if it were sent through a wrong sender.
Upvotes: 3